Condividi tramite


Uso di Output Protection Manager

In questo argomento viene descritto come usare Output Protection Manager (OPM) per proteggere il contenuto video mentre passa attraverso un connettore fisico a un dispositivo di visualizzazione. Questo argomento include le sezioni seguenti:

Il contenuto video Premium viene in genere crittografato per proteggerlo da duplicazioni non autorizzate. Naturalmente, il video deve essere decrittografato prima che venga visualizzato. I fotogrammi decrittografati non compressi devono quindi spostarsi tra un connettore fisico e il dispositivo di visualizzazione. I provider di contenuti possono richiedere che i fotogrammi video siano protetti a questo punto, mentre passano attraverso il connettore fisico.

A questo scopo esistono vari meccanismi di protezione, tra cui HDCP (High-Bandwidth Digital Content Protection) e DisplayPort Content Protection (DPCP) per gli output digitali; e Copy Generation Management System - Analogico (CGMS-A) per gli output analogici. In genere, questi meccanismi comportano la crittografia o lo scrambling del segnale prima che venga visualizzato.

OPM consente a un'applicazione di applicare meccanismi di protezione del contenuto nell'output video. Usando OPM, l'applicazione invia comandi e richieste di stato al driver di grafica tramite un canale attendibile e sicuro. OPM consente a un'applicazione di:

  • Verificare che un driver di grafica sia stato firmato da Microsoft.
  • Configurare un canale di comunicazione attendibile con il driver.
  • Applicare meccanismi di protezione del contenuto nell'output fisico.

OPM sostituisce il protocollo COPP (Certified Output Protection Protocol) e usa un'API simile. Per garantire la compatibilità con le versioni precedenti, l'interfaccia OPM può emulare l'interfaccia COPP. Le differenze tra OPM e COPP includono quanto segue:

  • OPM usa certificati X.509, mentre COPP usa un formato di certificato proprietario.
  • OPM supporta i ripetitori HDCP.
  • Le applicazioni che usano OPM non devono analizzare i messaggi di rinnovo del sistema HDCP .
  • OPM può essere usato quando la visualizzazione grafica usa la modalità clone. COPP non supporta la modalità clone.

Se l'applicazione usa il percorso multimediale protetto (PMP) per riprodurre contenuto video, non è necessario usare l'API OPM, perché PMP effettua tutte le chiamate OPM necessarie. L'API OPM è disponibile per le applicazioni che non usano pmP.

OPM è disponibile in Windows Vista e versioni successive, ma l'API non è stata resa pubblica fino a Windows 7. Per usare OPM in un'applicazione, è necessario avere le intestazioni e i file di libreria di Windows 7 SDK. Non è necessario ridistribuire dll per usare OPM in Windows Vista o Windows Server 2008.

Output video

Una scheda grafica può avere più di un output fisico, ognuno con le proprie funzionalità. Prima che un'applicazione riproduce contenuto protetto, deve impostare i meccanismi di protezione appropriati in ogni output video associato alla scheda grafica che visualizzerà il video. I meccanismi di protezione da applicare dipendono dalle regole di utilizzo per il contenuto.

Ogni output video è rappresentato da un'istanza dell'interfaccia IOPMVideoOutput . È possibile usare un handle di monitoraggio o dispositivo Direct3D per ottenere gli output video.

Uso di un dispositivo Direct3D:

  1. Ottenere il puntatore IDirect3DDevice9 per il dispositivo Direct3D che verrà usato dall'applicazione per creare superfici per contenere i fotogrammi video.
  2. Chiamare la funzione OPMGetVideoOutputsFromIDirect3DDevice9Object. Questa funzione alloca una matrice di puntatori IOPMVideoOutput , una per ogni output.

Uso degli handle di monitoraggio:

  1. Chiama EnumDisplayMonitors per ottenere gli handle HMONITOR che corrispondono alla finestra video. Diversi monitor possono essere associati alla stessa finestra, quindi è possibile ottenere diversi handle HMONITOR .
  2. Per ogni handle di monitoraggio, chiamare OPMGetVideoOutputsFromHMONITOR. Questa funzione alloca una matrice di puntatori IOPMVideoOutput , una per ogni output.

Inizializzazione di una sessione OPM

Prima che l'applicazione invii comandi OPM o richieste di stato, deve verificare che l'output video sia attendibile e stabilire una chiave di sessione. La chiave di sessione viene usata per firmare i dati scambiati tra l'applicazione e il driver grafico.

L'API OPM definisce un handshake che stabilisce l'attendibilità e imposta la chiave di sessione. È necessario eseguire questo handshake per ogni istanza dell'interfaccia IOPMVideoOutput , come indicato di seguito:

  1. Chiama IOPMVideoOutput::StartInitialization. Questo metodo recupera due parti di dati:

    • Numero casuale generato dal driver. Questo numero verrà usato per completare l'handshake.
    • Catena di certificati X.509 del driver.
  2. Verificare che la catena di certificati sia stata firmata da Microsoft.

    Nota

    La revoca dei certificati non rientra nell'ambito di OPM.

     

  3. Ottenere la chiave pubblica del driver dalla catena di certificati.

  4. Generare una chiave di sessione AES a 128 bit.

  5. Generare due numeri casuali a 32 bit:

    • Numero di sequenza iniziale per le richieste di stato OPM.
    • Numero di sequenza iniziale per i comandi OPM.

    Questi numeri devono essere generati usando un generatore di numeri pseudo-casuali crittografati, ad esempio CryptGenRandom.

  6. Copiare il numero casuale del driver (ottenuto nel passaggio 1), la chiave di sessione e i due numeri di sequenza in una struttura OPM_ENCRYPTED_INITIALIZATION_PARAMETERS, come descritto in IOPMVideoOutput::FinishInitialization.

  7. Crittografare la struttura OPM_ENCRYPTED_INITIALIZATION_PARAMETERS con RSAES-OAEP usando la chiave pubblica del driver, disponibile nel certificato del driver.

  8. Chiama IOPMVideoOutput::FinishInitialization.

Invio di richieste di stato OPM

Le richieste di stato OPM restituiscono informazioni sull'output video, ad esempio il tipo di connettore fisico e il livello di protezione corrente. Per un elenco dei tipi di richiesta, vedere Richieste di stato OPM.

Per inviare una richiesta di stato, seguire questa procedura.

  1. Inizializzare una struttura OPM_GET_INFO_PARAMETERS come illustrato nella tabella seguente.

    Membro Descrizione
    Omac Ignorare questo campo per il momento.
    rnRandomNumber Numero casuale a 128 bit sicuro a 128 bit. Ogni volta che si effettua una richiesta di stato, generare sempre un nuovo numero casuale, anche se si effettua la stessa richiesta. Archiviare il numero in una variabile, perché sarà necessario farvi riferimento in un secondo momento.
    guidInformation GUID che identifica la richiesta di stato. Per un elenco delle richieste di stato, vedere Richieste di stato OPM.
    ulSequenceNumber Numero di sequenza. Per la prima richiesta di stato, usare il numero di sequenza iniziale specificato nel metodo IOPMVideoOutput::FinishInitialization (passaggio 5 dell'inizializzazione di una sessione OPM). Ogni volta che si effettua un'altra richiesta di stato, incrementare questo numero di 1.
    abParameters Matrice di byte che contiene dati di input aggiuntivi per la richiesta. Il formato dei dati di input è elencato nell'argomento di riferimento per ogni richiesta di stato.
    cbParametersSize Dimensioni dei dati validi nella matrice abParameters . Il contenuto del resto della matrice non è definito.

     

  2. Calcolare il codice CBC MAC (OMAC-1) a chiave singola per calcolare un hash per il blocco di dati visualizzato dopo il membro omac e quindi impostare il membro omac su questo valore. Vedere Codice di esempio di OPM.

  3. Chiamare il metodo IOPMVideoOutput::GetInformation. Passare un puntatore alla struttura OPM_GET_INFO_PARAMETERS e un puntatore a una struttura OPM_REQUESTED_INFORMATION. La risposta del driver viene scritta nella struttura OPM_REQUESTED_INFORMATION .

    • Il membro omac di questa struttura contiene un OMAC calcolato per i dati che seguono questo membro.
    • Il membro abRequestedInformation è una matrice di byte che contiene i dati di output per la risposta. Il formato dei dati di output è elencato nell'argomento di riferimento per ogni richiesta di stato.
  4. Calcolare un OMAC per la struttura OPM_REQUESTED_INFORMATION, senza includere il membro omac. Verificare che OMAC corrisponda al valore nel membro omac .

  5. Assicurarsi che il membro cbRequestedInformationSize della struttura OPM_REQUESTED_INFORMATION restituisca le dimensioni corrette per i dati di output. Ad esempio, i dati di output per la query OPM_GET_CONNECTOR_TYPE sono una struttura OPM_STANDARD_INFORMATION, quindi il valore di cbRequestedInformationSize deve essere sizeof(OPM_STANDARD_INFORMATION).

  6. Eseguire il cast del membro abRequestedInformation della struttura OPM_REQUESTED_INFORMATION alla struttura dei dati di output corretta. Ad esempio, se la richiesta di stato è OPM_GET_CONNECTOR_TYPE, eseguire il cast abRequestedInformation in una struttura OPM_STANDARD_INFORMATION.

  7. Verificare che il membro rnRandomNumber della struttura dei dati di output corrisponda al valore di rnRandomNumber del passaggio 1.

  8. Controllare il membro ulStatusFlags della struttura dei dati di output, come descritto in Gestione di un output video disabilitato.

Se uno dei controlli nei passaggi da 5 a 8 ha esito negativo, l'applicazione deve interrompere la visualizzazione del contenuto protetto.

Invio di comandi OPM

I comandi OPM vengono usati per impostare il livello di protezione e altre impostazioni nell'output video. L'invio di un comando OPM è simile all'invio di una richiesta di stato, ad eccezione del fatto che non sono presenti dati di risposta dal driver. Per un elenco dei comandi, vedere Comandi OPM.

Per inviare un comando OPM, seguire questa procedura.

  1. Compilare una struttura OPM_CONFIGURE_PARAMETERS come illustrato nella tabella seguente.

    Membro Descrizione
    Omac Ignorare questo campo per il momento.
    guidSetting GUID che identifica il comando. Per un elenco dei comandi, vedere Comandi OPM.
    ulSequenceNumber Numero di sequenza. Per il primo comando, usare il numero di sequenza iniziale specificato nel metodo IOPMVideoOutput::FinishInitialization (passaggio 5 dell'inizializzazione di una sessione OPM). Ogni volta che si invia un altro comando, incrementare questo numero di 1.
    abParameters Matrice di byte che contiene dati di input aggiuntivi per il comando. Il formato dei dati di input è elencato nell'argomento di riferimento per ogni comando.
    cbSettingDataSize Dimensioni dei dati validi nella matrice abParameters . Il contenuto del resto della matrice non è definito.

     

  2. Calcolare un OMAC per il blocco di dati visualizzato dopo il membro omac e quindi impostare il membro omac su questo valore.

  3. Chiama IOPMVideoOutput::Configure.

Per la maggior parte dei comandi, è presente una richiesta di stato corrispondente che restituisce lo stato del comando. Ad esempio, il comando OPM_edizione StandardT_PROTECTION_LEVEL imposta il livello di protezione e il comando OPM_GET_VIRTUAL_PROTECTION_LEVEL ottiene il livello di protezione corrente.

Gestione di un output video disabilitato

Un output video potrebbe disabilitarsi in qualsiasi momento per impedire l'uso non autorizzato del contenuto video. Questo problema può verificarsi perché un meccanismo di protezione smette di funzionare, perché il driver rileva manomissioni o perché lo schermo è stato disconnesso dal connettore fisico. Mentre un output video è disabilitato, non vengono visualizzati fotogrammi video.

Mentre la protezione del contenuto è abilitata, un'applicazione deve eseguire periodicamente (almeno una volta ogni 2 secondi) i passaggi seguenti.

  1. Chiama IOPMVideoOutput::GetInformation per inviare la richiesta di stato OPM_GET_ACTUAL_PROTECTION_LEVEL o OPM_GET_VIRTUAL_PROTECTION_LEVEL. I dati restituiti per entrambi i comandi sono una struttura OPM_STANDARD_INFORMATION.
  2. Controllare il membro ulInformation della struttura OPM_STANDARD_INFORMATION . Questo membro contiene un flag che indica se la protezione del contenuto è ancora abilitata. Se la protezione del contenuto è disattivata, interrompere immediatamente la riproduzione del video.
  3. Se la protezione del contenuto è attivata, controllare il membro ulStatusFlags della struttura OPM_STANDARD_INFORMATION . Se non vengono impostati flag, l'output video funziona correttamente. In caso contrario, l'output video è disabilitato.

I flag seguenti sono definiti per ulStatusFlags.

Flag Descrizione
OPM_STATUS_LINK_LOST La protezione dell'output ha smesso di funzionare per qualche motivo; Ad esempio, il dispositivo di visualizzazione potrebbe essere scollegato dal connettore. Arrestare la riproduzione e disattivare tutti i meccanismi di protezione dell'output.
OPM_STATUS_RENEGOTIATION_REQUIRED L'applicazione deve ristabilire la sessione OPM. Rispondere come segue:
  1. Arresta la riproduzione.
  2. Disattivare tutti i meccanismi di protezione.
  3. Rilasciare l'interfaccia IOPMVideoOutput .
  4. Ricreare tutte le superfici video.
  5. Creare un nuovo oggetto OPM e tentare di ristabilire la protezione del contenuto. In caso di errore, visualizza un messaggio di errore all'utente. Non riprodurre altri contenuti video.
OPM_STATUS_REVOKED_HDCP_DEVICE_ATTACHED Questo flag si applica solo quando viene usato HDCP e indica la presenza di un dispositivo HDCP revocato. Arrestare la riproduzione e disattivare tutti i meccanismi di protezione in questo output video. Quando questo flag è impostato, viene impostato anche il flag OPM_STATUS_LINK_LOST .
OPM_STATUS_REVOKED_HDCP_DEVICE_ATTACHED Il driver ha rilevato manomissioni. Interrompere la riproduzione e non riprodurre più video usando questo output video. È anche consigliabile interrompere l'uso di altri output video, perché il sistema potrebbe essere compromesso.

 

Uso di HDCP per proteggere il contenuto

Questa sezione descrive come abilitare la protezione dell'output HDCP tramite OPM. Ecco una descrizione generale dei passaggi che l'applicazione deve eseguire. I dettagli vengono forniti più avanti in questa sezione.

  1. L'applicazione potrebbe dover fornire un SRM all'output video. Il meccanismo per la ricezione di SMS non rientra nell'ambito dell'interfaccia OPM. Ad esempio, le SPM potrebbero essere recapitate come parte di un flusso di trasmissione.
  2. L'applicazione abilita la protezione dell'output HDCP.
  3. L'applicazione riproduce il contenuto video. Periodicamente, l'applicazione esegue il polling del driver per assicurarsi che HDCP sia attivo.
  4. Al termine della riproduzione, l'applicazione disattiva HDCP.

Impostazione di SRM

Per impostare SRM, seguire questa procedura.

  1. Inizializzare una struttura OPM_edizione StandardT_HDCP_SRM_PARAMETERS con il numero di versione SRM.
  2. Archiviare SRM in una variabile.
  3. Inviare un comando OPM_edizione StandardT_HDCP_SRM all'output video. Usare la procedura descritta in Invio di comandi OPM.
  4. Inviare una richiesta di stato OPM_GET_CURRENT_HDCP_SRM_VERSION all'output video. Usare la procedura descritta in Invio di richieste di stato OPM. Questa richiesta di stato non include dati di input, pertanto il contenuto del membro abParameters della struttura OPM_GET_INFO_PARAMETERS non è definito.
  5. Quando viene restituito il metodo IOPMVideoOutput::GetInformation, la matrice abRequestedInformation nella struttura OPM_REQUESTED_INFORMATION contiene una struttura OPM_STANDARD_INFORMATION. Il membro ulInformation di questa struttura contiene il numero di versione dell'SRM corrente. Questo valore deve essere uguale al valore del passaggio 2.

Abilitazione di HDCP

Per abilitare HDCP, seguire questa procedura.

  1. Inizializzare una struttura OPM_edizione StandardT_PROTECTION_LEVEL_PARAMETERS con i valori seguenti:
    • ulProtectionType = OPM_PROTECTION_TYPE_HDCP
    • ulProtectionLevel = OPM_HDCP_ON
    • Riservato = 0
    • Reserved2 = 0
  2. Inviare un comando OPM_edizione StandardT_PROTECTION_LEVEL. I dati di input nella matrice abParameters sono la struttura OPM_edizione StandardT_PROTECTION_LEVEL_PARAMETERS.
  3. Inviare una richiesta di stato OPM_GET_VIRTUAL_PROTECTION_LEVEL per verificare se HDCP è abilitato. I primi 4 byte del membro abParameters della struttura OPM_GET_INFO_PARAMETERS contengono il valore OPM_PROTECTION_TYPE_HDCP.

Quando viene restituito il metodo GetInformation, la matrice abRequestedInformation nella struttura OPM_REQUESTED_INFORMATION contiene una struttura OPM_STANDARD_INFORMATION. Il membro ulInformation di questa struttura contiene un valore dell'enumerazione OPM_HDCP_PROTECTION_LEVEL . Se il valore è uguale a OPM_HDCP_ON, significa che HDCP è abilitato. In caso contrario, ripetere i passaggi da 1 a 2 finché HDCP non è abilitato o si verifica un errore. Ricordarsi di incrementare il numero di sequenza e generare un nuovo numero casuale ogni volta.

L'abilitazione di HDCP richiede in genere tra 100 e 200 millisecondi, ma può richiedere più tempo. Non presupporre che HDCP sia abilitato fino a quando non è stato verificato.

Al termine della riproduzione del contenuto protetto, disattivare HDCP. I passaggi sono uguali a per l'abilitazione di HDCP, ma nel passaggio 1 impostare ulProtectionLevel su OPM_HDCP_OFF.

Nota

Non abilitare HDCP se il tipo di connettore è OPM_CONNECTOR_TYPE_DISPLAYPORT_EMBEDDED. (Vedere Flag di tipo OPM Connessione or.

 

Output Protection Manager