GPU-Based protection du contenu
Cette rubrique décrit les fonctionnalités de protection du contenu vidéo qu’un pilote Graphics peut fournir.
- Introduction
- Vue d’ensemble du processus de décodage
- Chiffrement de mémoires tampons vidéo compressées pour le décodeur
- Envoi de commandes de canal authentifié
- Envoi de requêtes de canal authentifié
- Rubriques connexes
Introduction
Le diagramme suivant montre une vue simplifiée de la façon dont le contenu de la vidéo protégée transite par le pipeline pour être rendu.

Notes
Le chemin d’accès au média protégé (PMP) n’est pas représenté dans ce diagramme. Le workflow illustré ici peut se produire dans un processus PMP ou dans un processus d’application.
Le décodeur reçoit des données vidéo chiffrées et compressées à partir d’une source externe. Il est supposé également que le décodeur reçoit également une clé de chiffrement pour déchiffrer ces données. Cette rubrique ne décrit pas l’échange de clés entre la source et le décodeur vidéo, mais le PMP définit un mécanisme possible. Le GPU n’est pas impliqué à ce niveau.
Pour le décodage à accélération matérielle, le décodeur logiciel transmet le contenu vidéo compressé au GPU. Pour protéger ce contenu, le décodeur rechiffre les données, généralement en utilisant AES-CTR, avant de les transmettre à l’accélérateur matériel. Un mécanisme d’échange de clés est défini entre le décodeur et le pilote Graphics.
Les trames vidéo décodées sont stockées dans la mémoire vidéo, généralement en clair. À ce stade, les trames sont traitées et présentées. Il existe deux options principales pour la présentation.
- Les frames peuvent être présentés à l’aide d’une superposition matérielle. Pour plus d’informations, consultez prise en charge de la superposition matérielle.
- Les frames peuvent être présentés par la gestion de la fenêtre du Bureau (DWM) à l’aide d’une surface partagée.
La dernière étape consiste à afficher le cadre sur le moniteur, ce qui peut nécessiter une protection de liaison entre la carte graphique et le périphérique d’affichage. Un exemple de protection de liaison est High-Bandwidth la protection du contenu numérique (HDCP). La protection de liaison est configurée à l’aide de la protection de sortie (OPM). Cette rubrique ne décrit pas OPM ; Pour plus d’informations, consultez utilisation de Output Protection Manager.
Vue d’ensemble du processus de décodage
Lors du décodage accéléré par le matériel, le décodeur logiciel doit transmettre les données vidéo compressées à la carte graphique. Pour le contenu Premium, ces données doivent généralement être chiffrées, à l’aide d’un chiffrement à clé symétrique, avant d’être envoyées au GPU.
Pour chiffrer la vidéo en vue du décodage, le décodeur logiciel utilise les interfaces suivantes :
- IDirectXVideoDecoder. Représente l’appareil du décodeur DXVA, également appelé accélérateur.
- IDirect3DCryptoSession9. Représente une session de chiffrement, qui fournit la clé de chiffrement.
- IDirect3DAuthenticatedChannel9. Représente un canal authentifié qui permet au décodeur logiciel d’associer la session de chiffrement au décodeur DXVA.

Toutes ces interfaces sont obtenues à partir du périphérique Direct3D, comme suit :
| Interface | Création |
|---|---|
| IDirectXVideoDecoder | Appelez IDirectXVideoDecoderService :: CreateVideoDecoder. L’appareil de décodage DXVA est identifié par un GUID de profil DXVA. |
| IDirect3DCryptoSession9 | Appelez IDirect3DDevice9Video :: CreateCryptoSession. |
| IDirect3DAuthenticatedChannel9 | Appelez IDirect3DDevice9Video :: CreateAuthenticatedChannel. |
Notes
Pour obtenir un pointeur vers l’interface IDirect3DDevice9Video , appelez QueryInterface sur un appareil D3D9Ex.
Le canal authentifié fournit un canal de communication approuvé entre le décodeur logiciel et le pilote. Le canal de communication fonctionne comme suit :
- Le pilote fournit une chaîne de certificat X. 509 dont le certificat racine est signé par Microsoft.
- Le certificat contient une clé publique RSA pour le pilote.
- Le décodeur logiciel utilise la clé publique pour envoyer au pilote une clé de session AES 128 bits.
- Le décodeur logiciel envoie des requêtes et des commandes au canal authentifié.
- La clé de session est utilisée pour calculer les codes d’authentification de message (Mac) pour les requêtes et les commandes. Le pilote utilise les Mac pour vérifier l’intégrité des données de requête/commande, et le décodeur logiciel les utilise pour vérifier l’intégrité des données de réponse du pilote.
Chiffrement de mémoires tampons vidéo compressées pour le décodeur
Voici une vue d’ensemble de haut niveau du processus de chiffrement et de décodage :
Le décodeur logiciel reçoit un flux de données chiffrées à partir de la source vidéo. Le décodeur déchiffre ce flux.
Le décodeur logiciel négocie une clé de session avec la session de chiffrement.
Le décodeur logiciel utilise le canal authentifié pour associer la session de chiffrement à l’appareil de décodage DXVA.
Le décodeur logiciel place des données compressées dans des mémoires tampons DXVA qu’il obtient à partir de l’appareil de décodage DXVA (Accélérateur). Pour le contenu protégé, l’encodeur logiciel chiffre les données qui sont placées dans les tampons DXVA, à l’aide de la clé de session du chiffrement.
Notes
Certains pilotes utilisent une clé de contenu, au lieu de la clé de session, pour le chiffrement. La clé de contenu peut passer d’une image à l’autre.
Le décodeur envoie les mémoires tampons compressées chiffrées à l’accélérateur. Pour AES-CTR, le décodeur passe également le vecteur d’initialisation. Si une clé de contenu est utilisée, le décodeur transmet la clé de contenu, chiffrée à l’aide de la clé de session.
Direct3D offre une prise en charge standard de l’AES-CTR 128 bits, mais est conçu pour s’étendre à des types de chiffrement supplémentaires.
Les cinq sections suivantes fournissent des instructions plus détaillées.
- 1. interroger les fonctionnalités protection du contenu du pilote
- 2. configurer le canal authentifié
- 3. configurer la session de chiffrement
- 4. obtenir un descripteur de l’appareil décodeur DXVA
- 5. associer le décodeur DXVA à la session de chiffrement
1. interroger les fonctionnalités protection du contenu du pilote
Avant de tenter d’appliquer le chiffrement, procurez-vous les fonctionnalités de protection du contenu du pilote.
- Obtenir un pointeur vers l’appareil Direct3D 9.
- Appelez QueryInterface pour l’interface IDirect3DDevice9Video .
- Appelez IDirect3DDevice9Video :: GetContentProtectionCaps. Cette méthode remplit une structure D3DCONTENTPROTECTIONCAPS avec les fonctionnalités de protection du contenu du pilote.
En particulier, recherchez les fonctionnalités suivantes :
- Si le membre Caps contient l’indicateur D3DCPCAPS_SOFTWARE ou D3DCPCAPS_HARDWARE , le pilote peut effectuer le chiffrement.
- Le membre KeyExchangeType spécifie comment effectuer l’échange de clés pour la clé de session.
- Si le membre Caps contient l’indicateur D3DCPCAPS_CONTENTKEY , le pilote utilise une clé de contenu distincte pour le chiffrement. C’est important lorsque vous générez la clé de session.
Les fonctionnalités supplémentaires sont indiquées dans le membre Caps .
2. configurer le canal authentifié
L’étape suivante consiste à configurer le canal authentifié.
Appelez IDirect3DDevice9Video :: CreateAuthenticatedChannel pour créer le canal authentifié. Pour le paramètre ChannelType , spécifiez un type de canal qui correspond aux fonctionnalités du pilote.
- Le type de canal D3DAUTHENTICATEDCHANNEL_DRIVER_SOFTWARE correspond à D3DCPCAPS_SOFTWARE.
- Le type de canal D3DAUTHENTICATEDCHANNEL_DRIVER_HARDWARE correspond à D3DCPCAPS_HARDWARE.
La méthode CreateAuthenticatedChannel retourne un pointeur vers l’interface IDirect3DAuthenticatedChannel9 , ainsi qu’un handle vers le canal. Le descripteur est utilisé ultérieurement pour associer la session de chiffrement au canal authentifié.
Appelez IDirect3DAuthenticatedChannel9 :: GetCertificateSize pour connaître la taille du certificat X. 509 du pilote. Allouez une mémoire tampon de la taille requise.
Appelez IDirect3DAuthenticatedChannel9 :: GetCertificate pour récupérer le certificat. La méthode copie le certificat dans la mémoire tampon qui a été allouée à l’étape précédente.
Vérifiez que le certificat du pilote a été signé par Microsoft et qu’il n’a pas été révoqué.
Récupérez la clé publique à partir du certificat.
Générez une clé de session RSA aléatoire. Cette clé de session est utilisée pour signer les données envoyées au canal authentifié. Chiffrez la clé de session à l’aide de la clé publique du pilote.
Appelez IDirect3DAuthenticatedChannel9 :: NegotiateKeyExchange pour envoyer la clé de session chiffrée au pilote.
Initialisez le canal sécurisé comme suit :
- Remplissez une structure D3DAUTHENTICATEDCHANNEL_CONFIGUREINITIALIZE comme décrit dans la documentation.
- Envoyez la commande D3DAUTHENTICATEDCONFIGURE_INITIALIZE en appelant IDirect3DAuthenticatedChannel9 :: configure comme décrit dans la section envoi de commandes de canal authentifié. Cette commande contient les numéros de séquence de départ pour les commandes et les requêtes qui sont envoyées au canal authentifié.
Vérifiez le type de canal en envoyant une requête D3DAUTHENTICATEDQUERY_CHANNELTYPE au canal authentifié, comme décrit dans la section envoi de requêtes de canal authentifié. Vérifiez que le type de canal correspond à ce que vous avez spécifié dans la méthode CreateAuthenticatedChannel .
3. configurer la session de chiffrement
Ensuite, configurez la session de chiffrement et établissez la clé de session.
- Appelez IDirect3DDevice9Video :: CreateCryptoSession pour créer la session de chiffrement. Cette méthode retourne un pointeur vers l’interface IDirect3DCryptoSession9 , ainsi qu’un handle vers la session de chiffrement.
- Appelez IDirect3DCryptoSession9 :: GetCertificateSize pour connaître la taille du certificat X. 509 du pilote. Allouez une mémoire tampon de la taille requise.
- Appelez IDirect3DCryptoSession9 :: GetCertificate pour récupérer le certificat. La méthode copie le certificat dans la mémoire tampon qui a été allouée à l’étape précédente.
- Vérifiez que le certificat du pilote a été signé par Microsoft et qu’il n’a pas été révoqué.
- Récupérez la clé publique à partir du certificat.
- Générez une clé de session RSA aléatoire. Il s’agit d’une clé de session distincte de la clé de session du canal authentifié. Chiffrez la clé de session à l’aide de la clé publique du pilote.
- Appelez IDirect3DCryptoSession9 :: NegotiateKeyExchange pour envoyer la clé de session chiffrée au pilote.
- Si les fonctionnalités de protection du contenu incluent D3DCPCAPS_CONTENTKEY, créez une clé de contenu RSA aléatoire. Ce sera utilisé ultérieurement dans le processus de décodage.
4. obtenir un descripteur de l’appareil décodeur DXVA
Pour l’étape suivante, vous aurez besoin d’un handle vers l’appareil décodeur DXVA. Pour obtenir ce handle, remplissez une structure DXVA2_DecodeExecuteParams comme suit :
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);
Définissez le membre pExtensionData de la structure DXVA2_DecodeExecuteParams sur l’adresse d’une structure DXVA2_DecodeExtensionData .
Dans la structure DXVA2_DecodeExtensionData , définissez la fonction Member sur DXVA2_DECODE_GET_DRIVER_HANDLE. Définissez pPrivateOutputData sur l’adresse d’une mémoire tampon suffisamment grande pour stocker une valeur de handle . (Dans l’exemple précédent, cette mémoire tampon est la variable hDecodeDeviceHandle .)
Appelez ensuite IDirectXVideoDecoder :: Execute et transmettez l’adresse de la structure DXVA2_DecodeExecuteParams . Le handle du décodeur DXVA est retourné dans pPrivateOutputData.
5. associer le décodeur DXVA à la session de chiffrement
Ensuite, associez l’appareil de décodage DXVA à l’appareil Direct3D et à la session de chiffrement, comme suit :
- Obtenir un descripteur de l’appareil décodeur DXVA, comme décrit dans la section précédente.
- Obtenir un handle sur le périphérique Direct3D, en envoyant une requête D3DAUTHENTICATEDQUERY_DEVICEHANDLE au canal authentifié.
- Remplissez une structure D3DAUTHENTICATEDCHANNEL_CONFIGURECRYPTOSESSION avec les informations suivantes :
- Définissez le membre DXVA2DecodeHandle sur le descripteur de l’appareil décodeur DXVA.
- Définissez le membre CryptoSessionHandle sur le descripteur de la session de chiffrement. Ce handle est retourné par la méthode IDirect3DDevice9Video :: CreateCryptoSession .
- Définissez le membre DeviceHandle sur le descripteur de périphérique Direct3D.
- Appelez IDirect3DAuthenticatedChannel9 :: configure pour envoyer une commande D3DAUTHENTICATEDCONFIGURE_CRYPTOSESSION au canal authentifié.
Le diagramme suivant illustre l’échange de handles :

Le décodeur logiciel peut désormais utiliser la clé de session de chiffrement pour chiffrer les mémoires tampons vidéo compressées. Chaque mémoire tampon compressée aura son propre vecteur d’initialisation (IV) spécifié dans le membre pvPVPState de la structure DXVA2_DecodeBufferDesc .
Envoi de commandes de canal authentifié
Un ensemble de commandes est défini pour la configuration du canal authentifié et la définition de diverses protections de contenu. Pour obtenir la liste des commandes, consultez protection du contenu des commandes.
Pour envoyer une commande au canal authentifié, procédez comme suit.
- Renseignez la structure des données d’entrée. Cette structure de données est toujours une structure D3DAUTHENTICATEDCHANNEL_CONFIGURE_INPUT suivie de champs supplémentaires. Renseignez la structure D3DAUTHENTICATEDCHANNEL_CONFIGURE_INPUT comme indiqué dans le tableau suivant.
| Membre | Description |
|---|---|
| omac | Ignorez ce champ pour l’instant. |
| ConfigureType | GUID qui identifie la commande. Pour obtenir la liste des commandes, consultez protection du contenu des commandes. |
| hChannel | Handle du canal authentifié. |
| SequenceNumber | Numéro séquentiel. Le premier numéro de séquence est spécifié par l’envoi d’une commande D3DAUTHENTICATEDCONFIGURE_INITIALIZE . Chaque fois que vous envoyez une autre commande, incrémentez ce nombre de 1. Le numéro de séquence protège contre les attaques par relecture. [!Note] |
- Calculez la balise OMAC pour le bloc de données qui apparaît après le membre OMAC de la structure d’entrée. Copiez ensuite cette valeur de balise dans le membre OMAC .
- Appelez IDirect3DAuthenticatedChannel9 :: configure.
- Le pilote place la sortie de la commande dans la structure D3DAUTHENTICATEDCHANNEL_CONFIGURE_OUTPUT .
- Calculez la balise OMAC pour le bloc de données qui apparaît après le membre OMAC de la structure de sortie. Comparez ceci avec la valeur du membre OMAC . Échouent s’ils ne correspondent pas.
- Comparez les valeurs des membres ConfigureType, hChannel et de la structure de sortie à vos valeurs pour ces membres. Échouent s’ils ne correspondent pas.
- Incrémentez le numéro de séquence de la commande suivante.
Envoi de requêtes de canal authentifié
Un ensemble de requêtes est défini pour la récupération d’informations sur le canal authentifié. Pour obtenir la liste des requêtes, consultez protection du contenu des requêtes.
Pour envoyer une commande au canal authentifié, procédez comme suit.
- Renseignez la structure des données d’entrée. Cette structure de données est toujours une structure D3DAUTHENTICATEDCHANNEL_QUERY_INPUT , éventuellement suivie de champs supplémentaires. Renseignez la structure D3DAUTHENTICATEDCHANNEL_QUERY_INPUT comme indiqué dans le tableau suivant.
| Membre | Description |
|---|---|
| Affectée | GUID qui identifie la requête. Pour obtenir la liste des requêtes, consultez protection du contenu des requêtes. |
| hChannel | Handle du canal authentifié. |
| SequenceNumber | Numéro séquentiel. Le premier numéro de séquence est spécifié par l’envoi d’une commande D3DAUTHENTICATEDCONFIGURE_INITIALIZE . Chaque fois que vous envoyez une autre requête, incrémentez ce nombre de 1. Le numéro de séquence protège contre les attaques par relecture. [!Note] |
- Appelez IDirect3DAuthenticatedChannel9 :: Query.
- Le pilote place la sortie de la requête dans une structure D3DAUTHENTICATEDCHANNEL_QUERY_OUTPUT . Cette structure est suivie de champs supplémentaires, selon le type de requête.
- Calculez la balise OMAC pour le bloc de données qui apparaît après le membre OMAC de la structure de sortie. Comparez ceci avec la valeur du membre OMAC . Échouent s’ils ne correspondent pas.
- Comparez les valeurs des membres ConfigureType, hChannel et de la structure de sortie à vos valeurs pour ces membres. Échouent s’ils ne correspondent pas.
- Incrémentez le numéro de séquence de la requête suivante.