출력 보호 관리자 사용

이 항목에서는 OPM(출력 보호 관리자)을 사용하여 물리적 커넥터를 통해 디스플레이 디바이스로 이동할 때 비디오 콘텐츠를 보호하는 방법을 설명합니다. 이 항목에는 다음과 같은 섹션이 포함되어 있습니다.

프리미엄 비디오 콘텐츠는 일반적으로 무단 복제로부터 보호하기 위해 암호화됩니다. 물론 비디오가 표시되기 전에 암호를 해독해야 합니다. 암호 해독된 압축되지 않은 프레임은 물리적 커넥터를 가로질러 디스플레이 디바이스로 이동해야 합니다. 콘텐츠 공급자는 물리적 커넥터를 통해 이동할 때 이 시점에서 비디오 프레임을 보호해야 할 수 있습니다.

이를 위해 HDCP(고대역 디지털 콘텐츠 보호) 및 디지털 출력을 위한 DPCP(DisplayPort Content Protection)를 비롯한 다양한 보호 메커니즘이 있습니다. 및 복사 생성 관리 시스템 - 아날로그 출력을 위한 아날로그(CGMS-A) 일반적으로 이러한 메커니즘에는 디스플레이에 가기 전에 신호를 암호화하거나 스크램블링하는 작업이 포함됩니다.

OPM을 사용하면 애플리케이션이 비디오 출력에 콘텐츠 보호 메커니즘을 적용할 수 있습니다. 애플리케이션은 OPM을 사용하여 신뢰할 수 있는 보안 채널을 통해 명령 및 상태 요청을 그래픽 드라이버에 보냅니다. OPM을 사용하면 애플리케이션에서 다음을 수행할 수 있습니다.

  • Microsoft에서 그래픽 드라이버에 서명했는지 확인합니다.
  • 드라이버와 신뢰할 수 있는 통신 채널을 설정합니다.
  • 물리적 출력에 콘텐츠 보호 메커니즘을 적용합니다.

OPM은 COPP(Certified Output Protection Protocol)를 대체하고 유사한 API를 사용합니다. 이전 버전과의 호환성을 위해 OPM 인터페이스는 COPP 인터페이스를 에뮬레이트할 수 있습니다. OPM과 COPP 간의 차이점은 다음과 같습니다.

  • OPM은 X.509 인증서를 사용하고 COPP는 독점적인 인증서 형식을 사용합니다.
  • OPM은 HDCP 반복기를 지원합니다.
  • OPM을 사용하는 애플리케이션은 HDCP SRM(시스템 갱신성 메시지)을 구문 분석할 필요가 없습니다.
  • 그래픽 디스플레이에서 복제 모드를 사용하는 경우 OPM을 사용할 수 있습니다. COPP는 복제 모드를 지원하지 않습니다.

애플리케이션이 PMP(보호된 미디어 경로)를 사용하여 비디오 콘텐츠를 재생하는 경우 PMP가 필요한 모든 OPM 호출을 수행하므로 OPM API를 사용할 필요가 없습니다. OPM API는 PMP를 사용하지 않는 애플리케이션에 사용할 수 있습니다.

OPM은 Windows Vista 이상에서 사용할 수 있지만 API는 Windows 7까지 공개되지 않았습니다. 애플리케이션에서 OPM을 사용하려면 Windows 7 SDK의 헤더 및 라이브러리 파일이 있어야 합니다. Windows Vista 또는 Windows Server 2008에서 OPM을 사용하기 위해 DLL을 재배포할 필요가 없습니다.

비디오 출력

그래픽 어댑터는 각각 고유한 기능을 가진 둘 이상의 물리적 출력을 가질 수 있습니다. 애플리케이션이 보호된 콘텐츠를 재생하기 전에 비디오를 표시할 그래픽 카드 연결된 모든 비디오 출력에 적절한 보호 메커니즘을 설정해야 합니다. 적용할 보호 메커니즘은 콘텐츠에 대한 사용 규칙에 따라 달라집니다.

각 비디오 출력은 IOPMVideoOutput 인터페이스의 인스턴스로 표시됩니다. Direct3D 디바이스 또는 모니터 핸들을 사용하여 비디오 출력을 가져올 수 있습니다.

Direct3D 디바이스 사용:

  1. 애플리케이션이 비디오 프레임을 유지하는 표면을 만드는 데 사용할 Direct3D 디바이스에 대한 IDirect3DDevice9 포인터를 가져옵니다.
  2. OPMGetVideoOutputsFromIDirect3DDevice9Object 함수를 호출합니다. 이 함수는 각 출력에 하나씩 IOPMVideoOutput 포인터 배열을 할당합니다.

모니터 핸들 사용:

  1. EnumDisplayMonitors를 호출하여 비디오 창에 해당하는 HMONITOR 핸들을 가져옵니다. 여러 모니터를 동일한 창에 연결할 수 있으므로 여러 HMONITOR 핸들을 가져올 수 있습니다.
  2. 각 모니터 핸들에 대해 OPMGetVideoOutputsFromHMONITOR를 호출 합니다. 이 함수는 각 출력에 하나씩 IOPMVideoOutput 포인터 배열을 할당합니다.

OPM 세션 초기화

애플리케이션이 OPM 명령 또는 상태 요청을 보내기 전에 비디오 출력이 신뢰할 수 있는지 확인하고 세션 키를 설정해야 합니다. 세션 키는 애플리케이션과 그래픽 드라이버 간에 교환되는 데이터에 서명하는 데 사용됩니다.

OPM API는 트러스트를 설정하고 세션 키를 설정하는 핸드셰이크를 정의합니다. 다음과 같이 IOPMVideoOutput 인터페이스의 각 인스턴스에 대해 이 핸드셰이크를 수행해야 합니다.

  1. IOPMVideoOutput::StartInitialization을 호출 합니다. 이 메서드는 다음 두 가지 데이터를 검색합니다.

    • 드라이버에서 생성된 난수입니다. 이 번호를 사용하여 핸드셰이크를 완료합니다.
    • 드라이버의 X.509 인증서 체인입니다.
  2. Microsoft에서 인증서 체인에 서명했는지 확인합니다.

    참고 항목

    인증서 해지는 OPM의 범위를 벗어났습니다.

     

  3. 인증서 체인에서 드라이버의 공개 키를 가져옵니다.

  4. 128비트 AES 세션 키를 생성합니다.

  5. 두 개의 임의 32비트 숫자를 생성합니다.

    • OPM 상태 요청에 대한 시작 시퀀스 번호입니다.
    • OPM 명령에 대한 시작 시퀀스 번호입니다.

    이러한 숫자는 CryptGenRandom과 같은 암호화 보안 의사 난수 생성기를 사용하여 생성해야 합니다.

  6. IOPMVideoOutput::FinishInitialization에 설명된 대로 드라이버의 난수(1단계에서 얻은), 세션 키 및 두 시퀀스 번호를 OPM_ENCRYPTED_INITIALIZATION_PARAMETERS 구조로 복사합니다.

  7. 드라이버의 인증서에 있는 드라이버의 공개 키를 사용하여 RSAES-OAEP를 사용하여 OPM_ENCRYPTED_INITIALIZATION_PARAMETERS 구조를 암호화합니다.

  8. IOPMVideoOutput::FinishInitialization을 호출합니다.

OPM 상태 요청 보내기

OPM 상태 요청은 물리적 커넥터의 유형 및 현재 보호 수준과 같은 비디오 출력에 대한 정보를 반환합니다. 요청 유형 목록은 OPM 상태 요청을 참조 하세요.

상태 요청을 보내려면 다음 단계를 수행합니다.

  1. 다음 표와 같이 OPM_GET_INFO_PARAMETERS 구조를 초기화합니다.

    멤버 설명
    omac 지금은 이 필드를 건너뜁니다.
    rnRandomNumber 암호화된 보안 128비트 난수입니다. 상태 요청을 할 때마다 동일한 요청을 하는 경우에도 항상 새 난수를 생성합니다. 나중에 참조해야 하므로 변수에 숫자를 저장합니다.
    guidInformation 상태 요청을 식별하는 GUID입니다. 상태 요청 목록은 OPM 상태 요청을 참조하세요.
    ulSequenceNumber 시퀀스 번호입니다. 첫 번째 상태 요청의 경우 IOPMVideoOutput::FinishInitialization 메서드(OPM 세션 초기화 5단계)에서 지정한 시작 시퀀스 번호를 사용합니다. 다른 상태 요청을 할 때마다 이 수를 1씩 증분합니다.
    abParameters 요청에 대한 추가 입력 데이터가 포함된 바이트 배열입니다. 입력 데이터의 형식은 각 상태 요청에 대한 참조 항목에 나열됩니다.
    cbParametersSize abParameters 배열에 있는 유효한 데이터의 크기입니다 . 나머지 배열의 내용은 정의되지 않습니다.

     

  2. OMAC-1(One-key CBC MAC)을 계산하여 omac 멤버 다음에 나타나는 데이터 블록에 대한 해시를 계산한 다음, omac 멤버를 이 값으로 설정합니다. OPM 예제 코드를 참조하세요.

  3. IOPMVideoOutput::GetInformation 메서드를 호출합니다. OPM_GET_INFO_PARAMETERS 구조체에 대한 포인터와 OPM_REQUESTED_INFORMATION 구조체에 대한 포인터를 전달합니다. 드라이버의 응답은 OPM_REQUESTED_INFORMATION 구조에 기록됩니다.

    • 이 구조체의 omac 멤버에는 이 멤버 다음에 오는 데이터에 대해 계산된 OMAC가 포함됩니다.
    • abRequestedInformation 멤버는 응답에 대한 출력 데이터를 포함하는 바이트 배열입니다. 출력 데이터의 형식은 각 상태 요청에 대한 참조 항목에 나열됩니다.
  4. omac 멤버를 포함하지 않고 OPM_REQUESTED_INFORMATION 구조체에 대한 OMAC를 계산합니다. OMAC가 omac 멤버의 값과 일치하는지 확인합니다.

  5. OPM_REQUESTED_INFORMATION 구조체의 cbRequestedInformationSize 멤버가 출력 데이터에 대해 올바른 크기를 제공하는지 확인합니다. 예를 들어 OPM_GET_CONNECTOR_TYPE 쿼리 출력 데이터는 OPM_STANDARD_INFORMATION 구조이므로 cbRequestedInformationSize값은 이어야 sizeof(OPM_STANDARD_INFORMATION)합니다.

  6. OPM_REQUESTED_INFORMATION 구조체의 abRequestedInformation 멤버를 올바른 출력 데이터 구조로 캐스팅합니다. 예를 들어 상태 요청이 OPM_GET_CONNECTOR_TYPE 경우 abRequestedInformation을 OPM_STANDARD_INFORMATION 구조로 캐스팅합니다.

  7. 출력 데이터 구조의 rnRandomNumber 멤버가 1단계의 rnRandomNumber 값과 일치하는지 확인합니다.

  8. 사용 안 함 비디오 출력 처리에 설명된 대로 출력 데이터 구조의 ulStatusFlags 멤버를 확인합니다.

5~8단계의 검사 실패하면 애플리케이션에서 보호된 콘텐츠 표시를 중지해야 합니다.

OPM 명령 보내기

OPM 명령은 비디오 출력에 대한 보호 수준 및 기타 설정을 설정하는 데 사용됩니다. OPM 명령을 보내는 것은 드라이버의 응답 데이터가 없다는 점을 제외하고 상태 요청을 보내는 것과 유사합니다. 명령 목록은 OPM 명령을 참조 하세요.

OPM 명령을 보내려면 다음 단계를 수행합니다.

  1. 다음 표와 같이 OPM_CONFIGURE_PARAMETERS 구조를 채웁니다.

    멤버 설명
    omac 지금은 이 필드를 건너뜁니다.
    guidSetting 명령을 식별하는 GUID입니다. 명령 목록은 OPM 명령을 참조 하세요.
    ulSequenceNumber 시퀀스 번호입니다. 첫 번째 명령의 경우 IOPMVideoOutput::FinishInitialization 메서드(OPM 세션 초기화 5단계)에서 지정한 시작 시퀀스 번호를 사용합니다. 다른 명령을 보낼 때마다 이 숫자를 1씩 증분합니다.
    abParameters 명령에 대한 추가 입력 데이터가 포함된 바이트 배열입니다. 입력 데이터의 형식은 각 명령에 대한 참조 항목에 나열됩니다.
    cbSettingDataSize abParameters 배열에 있는 유효한 데이터의 크기입니다 . 나머지 배열의 내용은 정의되지 않습니다.

     

  2. omac 멤버 다음에 나타나는 데이터 블록에 대한 OMAC를 계산한 다음 omac 멤버를 이 값으로 설정합니다.

  3. IOPMVideoOutput::Configure를 호출 합니다.

대부분의 명령에는 명령의 상태 반환하는 해당 상태 요청이 있습니다. 예를 들어 OPM_SET_PROTECTION_LEVEL 명령은 보호 수준을 설정하고 OPM_GET_VIRTUAL_PROTECTION_LEVEL 명령은 현재 보호 수준을 가져옵니다.

사용 안 함 비디오 출력 처리

비디오 출력은 비디오 콘텐츠의 무단 사용을 방지하기 위해 언제든지 자신을 사용하지 않도록 설정할 수 있습니다. 보호 메커니즘 작동이 중지되거나 드라이버가 변조를 감지하거나 실제 커넥터에서 디스플레이 연결이 끊어졌기 때문에 이 문제가 발생할 수 있습니다. 비디오 출력을 사용하지 않도록 설정하면 비디오 프레임이 표시되지 않습니다.

콘텐츠 보호를 사용하는 동안 애플리케이션은 주기적으로(2초마다 한 번 이상) 다음 단계를 수행해야 합니다.

  1. IOPMVideoOutput::GetInformation을 호출하여 OPM_GET_ACTUAL_PROTECTION_LEVEL 또는 OPM_GET_VIRTUAL_PROTECTION_LEVEL 상태 요청을 보냅니다. 두 명령의 반환 데이터는 OPM_STANDARD_INFORMATION 구조입니다.
  2. OPM_STANDARD_INFORMATION 구조체의 ulInformation 멤버를 확인합니다. 이 멤버에는 콘텐츠 보호를 계속 사용할 수 있는지 여부를 나타내는 플래그가 포함되어 있습니다. 콘텐츠 보호가 해제된 경우 즉시 비디오 재생을 중지합니다.
  3. 콘텐츠 보호가 설정되면 OPM_STANDARD_INFORMATION 구조체의 ulStatusFlags 멤버를 검사. 플래그가 설정되지 않은 경우 비디오 출력이 제대로 작동합니다. 그렇지 않으면 비디오 출력을 사용할 수 없습니다.

다음 플래그는 ulStatusFlags에 대해 정의됩니다.

Flag 설명
OPM_STATUS_LINK_LOST 출력 보호가 어떤 이유로 작동을 중지했습니다. 예를 들어 디스플레이 디바이스가 커넥터에서 분리될 수 있습니다. 재생을 중지하고 모든 출력 보호 메커니즘을 해제합니다.
OPM_STATUS_RENEGOTIATION_REQUIRED 애플리케이션은 OPM 세션을 다시 설정해야 합니다. 다음과 같이 응답합니다.
  1. 재생을 중지합니다.
  2. 모든 보호 메커니즘을 해제합니다.
  3. IOPMVideoOutput 인터페이스를 해제합니다.
  4. 모든 비디오 화면을 다시 만듭니다.
  5. 새 OPM 개체를 만들고 콘텐츠 보호를 다시 설정하려고 합니다. 실패하면 사용자에게 오류 메시지를 표시합니다. 더 이상 비디오 콘텐츠를 재생하지 마세요.
OPM_STATUS_REVOKED_HDCP_DEVICE_ATTACHED 이 플래그는 HDCP를 사용하는 경우에만 적용되며 해지된 HDCP 디바이스가 있음을 나타냅니다. 재생을 중지하고 이 비디오 출력에서 모든 보호 메커니즘을 해제합니다. 이 플래그가 설정 되면 OPM_STATUS_LINK_LOST 플래그도 설정됩니다.
OPM_STATUS_REVOKED_HDCP_DEVICE_ATTACHED 드라이버가 변조를 감지했습니다. 재생을 중지하고 이 비디오 출력을 사용하여 더 이상 비디오를 재생하지 마세요. 시스템이 손상될 수 있으므로 다른 비디오 출력 사용을 중지하는 것도 좋습니다.

 

HDCP를 사용하여 콘텐츠 보호

이 섹션에서는 OPM을 사용하여 HDCP 출력 보호를 사용하도록 설정하는 방법을 설명합니다. 다음은 애플리케이션이 수행해야 하는 단계의 일반적인 개요입니다. 세부 정보는 이 섹션의 뒷부분에서 제공됩니다.

  1. 애플리케이션은 비디오 출력에 SRM을 제공해야 할 수 있습니다. SRM을 수신하는 메커니즘은 OPM 인터페이스의 범위를 벗어났습니다. 예를 들어 SRM은 브로드캐스트 스트림의 일부로 배달될 수 있습니다.
  2. 애플리케이션은 HDCP 출력 보호를 사용하도록 설정합니다.
  3. 애플리케이션은 비디오 콘텐츠를 재생합니다. 애플리케이션은 주기적으로 드라이버를 폴링하여 HDCP가 켜져 있는지 확인합니다.
  4. 재생이 완료되면 애플리케이션이 HDCP를 해제합니다.

SRM 설정

SRM을 설정하려면 다음 단계를 수행합니다.

  1. SRM 버전 번호를 사용하여 OPM_SET_HDCP_SRM_PARAMETERS 구조를 초기화합니다.
  2. 변수에 SRM을 저장합니다.
  3. 비디오 출력에 OPM_SET_HDCP_SRM 명령을 보냅니다. OPM 명령 보내기에 설명된 절차를 사용합니다.
    • OPM_CONFIGURE_PARAMETERS 구조체의 abParameters 멤버에는 OPM_SET_HDCP_SRM_PARAMETERS 구조체가 포함됩니다.
    • IOPMVideoOutput::Configure 메서드의 pbAdditionalParameters 매개 변수는 SRM을 포함하는 변수를 가리킵니다.
  4. 비디오 출력에 OPM_GET_CURRENT_HDCP_SRM_VERSION 상태 요청을 보냅니다. OPM 상태 요청 보내기에 설명된 절차를 사용합니다. 이 상태 요청에는 입력 데이터가 없으므로 OPM_GET_INFO_PARAMETERS 구조체의 abParameters 멤버의 콘텐츠가 정의되지 않습니다.
  5. IOPMVideoOutput::GetInformation 메서드가 반환되면 OPM_REQUESTED_INFORMATION 구조체의 abRequestedInformation 배열에는 OPM_STANDARD_INFORMATION 구조체가 포함됩니다. 이 구조체의 ulInformation 멤버에는 현재 SRM의 버전 번호가 포함됩니다. 이 값은 2단계의 값과 같아야 합니다.

HDCP 사용

HDCP를 사용하도록 설정하려면 다음 단계를 수행합니다.

  1. 다음 값을 사용하여 OPM_SET_PROTECTION_LEVEL_PARAMETERS 구조를 초기화합니다.
    • ulProtectionType = OPM_PROTECTION_TYPE_HDCP
    • ulProtectionLevel = OPM_HDCP_ON
    • 예약 = 0
    • Reserved2 = 0
  2. OPM_SET_PROTECTION_LEVEL 명령을 보냅니다. abParameters 배열의 입력 데이터는 OPM_SET_PROTECTION_LEVEL_PARAMETERS 구조체입니다.
  3. OPM_GET_VIRTUAL_PROTECTION_LEVEL 상태 요청을 보내 HDCP를 사용할 수 있는지 여부를 검사. OPM_GET_INFO_PARAMETERS 구조체의 abParameters 멤버의 처음 4바이트에는 OPM_PROTECTION_TYPE_HDCP이 포함됩니다.

GetInformation 메서드가 반환될 때 OPM_REQUESTED_INFORMATION 구조체의 abRequestedInformation 배열에는 OPM_STANDARD_INFORMATION 구조체가 포함됩니다. 이 구조체의 ulInformation 멤버는 OPM_HDCP_PROTECTION_LEVEL 열거형의 값을 포함합니다. 값이 OPM_HDCP_ON으면 HDCP가 사용됨을 의미합니다. 그렇지 않으면 HDCP를 사용하도록 설정하거나 오류가 발생할 때까지 1~2단계를 반복합니다. (시퀀스 번호를 증가시키고 매번 새 난수를 생성해야 합니다.)

HDCP를 사용하도록 설정하려면 일반적으로 100~200밀리초가 걸리지만 더 오래 걸릴 수 있습니다. HDCP를 확인할 때까지 사용하도록 설정되었다고 가정하지 마세요.

애플리케이션이 보호된 콘텐츠 재생을 마치면 HDCP를 끕니다. 단계는 HDCP를 사용하도록 설정하는 단계와 동일하지만 1단계에서 ulProtectionLevelOPM_HDCP_OFF 설정합니다.

참고 항목

커넥터 유형이 OPM_CONNECTOR_TYPE_DISPLAYPORT_EMBEDDED 경우 HDCP를 사용하도록 설정하지 마세요. (참조)OPM 커넥트 형식 플래그)

 

출력 보호 관리자