Compartir a través de


Envío de solicitudes de estado de COPP

[La característica asociada a esta página, DirectShow, es una característica heredada. Se ha reemplazado por MediaPlayer, IMFMediaEngine y Captura de audio/vídeo en Media Foundation. Esas características se han optimizado para Windows 10 y Windows 11. Microsoft recomienda encarecidamente que el nuevo código use MediaPlayer, IMFMediaEngine y Audio/Video Capture en Media Foundation en lugar de DirectShow, siempre que sea posible. Microsoft sugiere que el código existente que usa las API heredadas se reescriba para usar las nuevas API si es posible.

Para enviar una solicitud de estado del Protocolo de protección de salida certificada (COPP), rellene una estructura AMCOPPStatusInput con los datos de solicitud. Los miembros de la estructura son:

  • rApp. Número aleatorio de 128 bits, escrito como GUID. El mismo número se devuelve en la respuesta del controlador. Debe asignar el número aleatorio en el montón y, a continuación, copiarlo en la estructura. Esto protege contra ataques en los que el atacante modifica el contenido de la estructura AMCOPPStatusInput .
  • guidStatusRequestID. GUID que identifica la solicitud. Consulte Referencia de consulta COPP.
  • dwSequence. Número de secuencia de estado. Incremente este valor después de cada solicitud de estado. (En la sección Iniciando una sesión COPP, este valor se muestra como uStatusSeq en los ejemplos de código).
  • cbSizeData. Tamaño, en bytes, de los datos adicionales necesarios para la solicitud.
  • StatusData. Datos de la solicitud de estado.

Pase la estructura AMCOPPStatusInput al método IAMCertifiedOutputProtection::P rotectionStatus . Por ejemplo, el código siguiente envía una solicitud de estado que consulta qué mecanismos de protección están 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 respuesta se escribe en el miembro COPPStatus de la estructura AMCOPPStatusOutput . El tamaño de los datos válidos en la respuesta se da en el miembro cbSizeData . Para garantizar la integridad del mensaje, el controlador calcula un código de autenticación de mensajes (MAC) mediante el algoritmo OMAC 1 y devuelve este valor en el miembro macKDI de la estructura. La aplicación debe comprobar este valor de la siguiente manera:

  1. Calcule la etiqueta OMAC para el bloque de datos que aparece después del miembro macKDI de la estructura AMCOPPStatusOutput (es decir, cbSizeData más COPPStatus).
  2. Compare esta etiqueta con el valor de macKDI, con un memcmp recto.

El algoritmo OMAC 1 se describe en detalle en https://www.nuee.nagoya-u.ac.jp/labs/tiwata/omac/omac.html. COPP usa los siguientes parámetros de OMAC-1:

  • E = AES
  • t = 128 bits

Los datos devueltos desde la solicitud de estado siempre comienzan con dos elementos:

  • El mismo valor de rApp que pasó la aplicación. Debe comprobar que este valor coincide con el valor original almacenado en el montón.
  • Valor de COPP_StatusFlags que indica si el estado de protección de salida ha cambiado.

Dado que la conexión se puede perder o volver a configurar, la aplicación debe sondear periódicamente el controlador para el estado actual. Si se establece la marca COPP_RenegotiationRequired, la aplicación debe intentar restablecer el nivel de protección. Si se establece la marca COPP_LinkLost, la aplicación debe dejar de reproducir el contenido. Por ejemplo, se puede devolver la marca COPP_LinkLost porque el usuario desconectó el conector de salida. La aplicación debe liberar la instancia actual de VMR, crear una nueva instancia de VMR y establecer una nueva sesión copP (incluido el intercambio de claves y la validación de certificados).

Uso del Protocolo de protección de salida certificada (COPP)