Invio di richieste di stato COPP

[La funzionalità associata a questa pagina, DirectShow, è una funzionalità legacy. È stata sostituita da MediaPlayer, IMFMediaEngine e Audio/Video Capture in Media Foundation. Queste funzionalità sono state ottimizzate per Windows 10 e Windows 11. Microsoft consiglia vivamente che il nuovo codice usi MediaPlayer, IMFMediaEngine e Audio/Video Capture in Media Foundation invece di DirectShow, quando possibile. Microsoft suggerisce che il codice esistente che usa le API legacy venga riscritto per usare le nuove API, se possibile.

Per inviare una richiesta di stato COPP (Certified Output Protection Protocol), compilare una struttura AMCOPPStatusInput con i dati della richiesta. I membri della struttura sono:

  • rApp. Numero casuale a 128 bit, digitato come GUID. Lo stesso numero viene restituito nella risposta del driver. È necessario allocare il numero casuale nell'heap e quindi copiarlo nella struttura. Questo protegge dagli attacchi in cui l'utente malintenzionato modifica il contenuto della struttura AMCOPPStatusInput .
  • guidStatusRequestID. GUID che identifica la richiesta. Vedere Informazioni di riferimento sulle query COPP.
  • dwSequence. Numero di sequenza di stato. Incrementare questo valore dopo ogni richiesta di stato. Nella sezione Avvio di una sessione COPP questo valore viene visualizzato come uStatusSeq negli esempi di codice.
  • cbSizeData. Dimensione, in byte, di eventuali dati aggiuntivi necessari per la richiesta.
  • StatusData. Dati per la richiesta di stato.

Passare la struttura AMCOPPStatusInput al metodo IAMCertifiedOutputProtection::P rotectionStatus . Ad esempio, il codice seguente invia una richiesta di stato che esegue una query sui meccanismi di protezione disponibili:

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 risposta viene scritta nel membro COPPStatus della struttura AMCOPPStatusOutput . Le dimensioni dei dati validi nella risposta sono specificate nel membro cbSizeData . Per garantire l'integrità del messaggio, il driver calcola un codice mac (Message Authentication Code) usando l'algoritmo OMAC 1 e restituisce questo valore nel membro macKDI della struttura. L'applicazione deve verificare questo valore come segue:

  1. Calcolare il tag OMAC per il blocco di dati visualizzato dopo il membro macKDI della struttura AMCOPPStatusOutput (in altre parole , cbSizeData più COPPStatus).
  2. Confrontare questo tag con il valore in macKDI, usando un memcmp dritto.

L'algoritmo OMAC 1 è descritto in dettaglio in https://www.nuee.nagoya-u.ac.jp/labs/tiwata/omac/omac.html. COPP usa i parametri OMAC-1 seguenti:

  • E = AES
  • t = 128 bit

I dati restituiti dalla richiesta di stato iniziano sempre con due elementi:

  • Stesso valore di rApp passato dall'applicazione. È necessario verificare che questo valore corrisponda al valore originale archiviato nell'heap.
  • Valore COPP_StatusFlags che indica se lo stato di protezione dell'output è stato modificato.

Poiché la connessione può essere persa o riconfigurata, l'applicazione deve eseguire periodicamente il polling del driver per lo stato corrente. Se il flag COPP_RenegotiationRequired è impostato, l'applicazione deve tentare di reimpostare il livello di protezione. Se il flag COPP_LinkLost è impostato, l'applicazione deve interrompere la riproduzione del contenuto. Ad esempio, il flag COPP_LinkLost può essere restituito perché l'utente ha disconnesso il connettore di output. L'applicazione deve rilasciare l'istanza corrente di VMR, creare una nuova istanza di VMR e stabilire una nuova sessione COPP (inclusa la convalida dello scambio di chiavi e del certificato).

Uso del protocollo COPP (Certified Output Protection Protocol)