COPP 상태 요청 보내기

[이 페이지와 연결된 기능인 DirectShow는 레거시 기능입니다. MediaPlayer, IMFMediaEngine 및 Media Foundation의 오디오/비디오 캡처로 대체되었습니다. 이러한 기능은 Windows 10 및 Windows 11 최적화되었습니다. 가능한 경우 새 코드가 DirectShow 대신 Media Foundation에서 MediaPlayer, IMFMediaEngine오디오/비디오 캡처를 사용하는 것이 좋습니다. 가능한 경우 레거시 API를 사용하는 기존 코드를 다시 작성하여 새 API를 사용하도록 제안합니다.]

COPP(Certified Output Protection Protocol) 상태 요청을 보내려면 AMCOPPStatusInput 구조를 요청 데이터로 채웁니다. 구조체 멤버는 다음과 같습니다.

  • rApp. GUID로 입력된 128비트 난수입니다. 드라이버의 응답에 동일한 숫자가 반환됩니다. 힙에 난수를 할당한 다음 구조체에 복사해야 합니다. 공격자가 AMCOPPStatusInput 구조체의 내용을 수정하는 공격을 방어합니다.
  • guidStatusRequestID. 요청을 식별하는 GUID입니다. COPP 쿼리 참조를 참조하세요.
  • dwSequence. 상태 시퀀스 번호입니다. 각 상태 요청 후에 이 값을 증분합니다. COPP 세션 시작 섹션에서 이 값은 코드 예제에서 uStatusSeq 로 표시됩니다.
  • cbSizeData. 요청에 필요한 추가 데이터의 크기(바이트)입니다.
  • StatusData. 상태 요청에 대한 데이터입니다.

AMCOPPStatusInput 구조체를 IAMCertifiedOutputProtection::P rotectionStatus 메서드에 전달합니다. 예를 들어 다음 코드는 사용 가능한 보호 메커니즘을 쿼리하는 상태 요청을 보냅니다.

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;

응답은 AMCOPPStatusOutput 구조체의 COPPStatus 멤버에 기록됩니다. 응답에서 유효한 데이터의 크기는 cbSizeData 멤버에 제공됩니다. 메시지의 무결성을 보장하기 위해 드라이버는 OMAC 1 알고리즘을 사용하여 MAC(메시지 인증 코드)을 계산하고 구조체의 macKDI 멤버에 이 값을 반환합니다. 애플리케이션은 다음과 같이 이 값을 확인해야 합니다.

  1. AMCOPPStatusOutput 구조체의 macKDI 멤버 다음에 나타나는 데이터 블록에 대한 OMAC 태그를 계산합니다(즉, cbSizeDataCOPPStatus).
  2. 직선 memcmp를 사용하여 이 태그를 macKDI의 값과 비교합니다.

OMAC 1 알고리즘은 에 자세히 설명되어 있습니다 https://www.nuee.nagoya-u.ac.jp/labs/tiwata/omac/omac.html. COPP는 다음 OMAC-1 매개 변수를 사용합니다.

  • E = AES
  • t = 128비트

상태 요청에서 반환된 데이터는 항상 두 개의 항목으로 시작됩니다.

  • 애플리케이션에서 전달한 것과 동일한 rApp 값입니다. 이 값이 힙에 저장된 원래 값과 일치하는지 확인해야 합니다.
  • 출력 보호 상태 변경되었는지 여부를 나타내는 COPP_StatusFlags 값입니다.

연결을 끊거나 다시 구성할 수 있으므로 애플리케이션은 드라이버에서 현재 상태 주기적으로 폴링해야 합니다. COPP_RenegotiationRequired 플래그가 설정된 경우 애플리케이션은 보호 수준을 다시 설정하려고 시도해야 합니다. COPP_LinkLost 플래그가 설정된 경우 애플리케이션은 콘텐츠 재생을 중지해야 합니다. 예를 들어 사용자가 출력 커넥터의 연결을 끊으므로 COPP_LinkLost 플래그를 반환할 수 있습니다. 애플리케이션은 VMR의 현재 instance 해제하고, VMR의 새 instance 만들고, 새 COPP 세션(키 교환 및 인증서 유효성 검사 포함)을 설정해야 합니다.

COPP(Certified Output Protection Protocol) 사용