Partager via


Envoi de demandes d’état COPP

[La fonctionnalité associée à cette page, DirectShow, est une fonctionnalité héritée. Il a été remplacé par MediaPlayer, IMFMediaEngine et Audio/Video Capture dans Media Foundation. Ces fonctionnalités ont été optimisées pour Windows 10 et Windows 11. Microsoft recommande vivement au nouveau code d’utiliser MediaPlayer, IMFMediaEngine et La capture audio/vidéo dans Media Foundation au lieu de DirectShow, lorsque cela est possible. Microsoft suggère que le code existant qui utilise les API héritées soit réécrit pour utiliser les nouvelles API si possible.]

Pour envoyer une requête copp (Certified Output Protection Protocol) status, renseignez une structure AMCOPPStatusInput avec les données de requête. Les membres de la structure sont les suivants :

  • rApp. Nombre aléatoire 128 bits, tapé en tant que GUID. Le même nombre est retourné dans la réponse du pilote. Vous devez allouer le nombre aléatoire sur le tas, puis le copier dans la structure. Cela protège contre les attaques lorsque l’attaquant modifie le contenu de la structure AMCOPPStatusInput .
  • guidStatusRequestID. GUID qui identifie la demande. Consultez Informations de référence sur les requêtes COPP.
  • dwSequence. Numéro de séquence status. Incrémentez cette valeur après chaque requête status. (Dans la section Lancement d’une session COPP, cette valeur est affichée sous la forme uStatusSeq dans les exemples de code.)
  • cbSizeData. Taille, en octets, de toutes les données supplémentaires nécessaires pour la demande.
  • StatusData. Données pour la demande de status.

Passez la structure AMCOPPStatusInput à la méthode IAMCertifiedOutputProtection::P rotectionStatus . Par exemple, le code suivant envoie une requête status qui interroge les mécanismes de protection disponibles :

AMCOPPStatusInput input;
AMCOPPStatusOutput output;

// Create a 128-bit random number.
GUID *pGuid = new GUID();
if (pGuid == NULL)
{
    // Handle out-of-memory condition.
}
CryptGenRandom(hCSP, sizeof(GUID), (BYTE*)pGuid);  

// Copy the random number into the command structure.
memcpy(&input.rApp, pGuid, sizeof(GUID));

// Fill in the other data.
input.guidStatusRequestID = DXVA_COPPQueryProtectionType; // Request type.
input.dwSequence = uStatusSeq;  // Status sequence number.
input.cbSizeData = 0            // No other data for this query.

// Send the request.
hr = pCOPP->ProtectionStatus(&input, &output);

// Increment the sequence number each time.
++uStatusSeq;

La réponse est écrite dans le membre COPPStatus de la structure AMCOPPStatusOutput . La taille des données valides dans la réponse est indiquée dans le membre cbSizeData . Pour garantir l’intégrité du message, le pilote calcule un code d’authentification de message (MAC) à l’aide de l’algorithme OMAC 1 et retourne cette valeur dans le membre macKDI de la structure. L’application doit vérifier cette valeur comme suit :

  1. Calculez la balise OMAC pour le bloc de données qui apparaît après le membre macKDI de la structure AMCOPPStatusOutput (en d’autres termes, cbSizeData plus COPPStatus).
  2. Comparez cette balise avec la valeur dans macKDI, à l’aide d’un memcmp droit.

L’algorithme OMAC 1 est décrit en détail dans https://www.nuee.nagoya-u.ac.jp/labs/tiwata/omac/omac.html. COPP utilise les paramètres OMAC-1 suivants :

  • E = AES
  • t = 128 bits

Les données retournées par la demande de status commencent toujours par deux éléments :

  • La même valeur de rApp qui a été transmise par l’application. Vous devez vérifier que cette valeur correspond à la valeur d’origine stockée sur le tas.
  • Valeur COPP_StatusFlags qui indique si le status de protection de sortie a changé.

Étant donné que la connexion peut être perdue ou reconfigurée, l’application doit interroger régulièrement le pilote pour connaître la status actuelle. Si l’indicateur COPP_RenegotiationRequired est défini, l’application doit tenter de réinitialiser le niveau de protection. Si l’indicateur COPP_LinkLost est défini, l’application doit cesser de lire le contenu. Par exemple, l’indicateur COPP_LinkLost peut être retourné, car l’utilisateur a déconnecté le connecteur de sortie. L’application doit libérer la instance actuelle de la machine virtuelle, créer un instance du VMR et établir une nouvelle session COPP (y compris l’échange de clés et la validation de certificat).

Utilisation du protocole COPP (Certified Output Protection Protocol)