다음을 통해 공유


D3D11 비디오를 사용하여 콘텐츠 보호 GPU-Based

이 항목에서는 그래픽 드라이버가 제공할 수 있는 비디오 콘텐츠 보호 기능에 대해 설명합니다.

소개

다음 다이어그램은 보호된 비디오 콘텐츠가 렌더링될 파이프라인을 통해 이동하는 방식을 간략하게 보여 줍니다.

보호된 비디오 콘텐츠를 보여 주는 다이어그램

참고

PMP( 보호된 미디어 경로 )는 이 다이어그램에 표시되지 않습니다. 여기에 표시된 데이터 흐름은 PMP 프로세스 내에서 또는 애플리케이션 프로세스 내에서 발생할 수 있습니다.

 

디코더는 외부 원본에서 암호화된 압축된 비디오 데이터를 받습니다. 또한 디코더가 이 데이터의 암호를 해독하는 암호화 키를 수신하는 것으로 가정합니다. 이 항목에서는 비디오 원본과 디코더 간의 키 교환에 대해 설명하지 않지만 PMP는 하나의 가능한 메커니즘을 정의합니다. GPU는 이 단계에서 포함되지 않습니다.

하드웨어 가속 디코딩의 경우 소프트웨어 디코더는 압축된 비디오 콘텐츠를 GPU에 전달합니다. 이 콘텐츠를 보호하기 위해 디코더는 데이터를 하드웨어 가속기로 전달하기 전에 일반적으로 AES-CTR을 사용하여 데이터를 다시 암호화합니다. 키 교환 메커니즘은 디코더와 그래픽 드라이버 간에 정의됩니다.

디코딩된 비디오 프레임은 일반적으로 명확한 비디오 메모리에 저장됩니다. 이 시점에서 프레임이 처리된 다음 표시됩니다. 프레젠테이션에는 두 가지 기본 옵션이 있습니다.

  • D3D9 API를 사용하는 경우 하드웨어 오버레이를 사용하여 프레임을 표시할 수 있습니다. 하드웨어는 D3D11에서 과도하게 지원되지 않습니다. 자세한 내용은 하드웨어 오버레이 지원을 참조하세요.
  • 프레임은 공유 화면을 사용하여 DWM(데스크톱 창 관리)에서 표시할 수 있습니다.

마지막 단계는 그래픽 카드 디스플레이 디바이스 간에 링크 보호가 필요할 수 있는 모니터에 프레임을 표시하는 것입니다. 링크 보호의 예는 High-Bandwidth HDCP(Digital Content Protection)입니다. 연결 보호는 OPM( 출력 보호 관리자 )을 사용하여 구성됩니다. 이 항목에서는 OPM에 대해 설명하지 않습니다. 자세한 내용은 출력 보호 관리자 사용을 참조하세요.

디코딩 프로세스 개요

하드웨어 가속 디코딩 중에 소프트웨어 디코더는 압축된 비디오 데이터를 그래픽 카드 전달해야 합니다. 프리미엄 콘텐츠의 경우 일반적으로 GPU로 전송되기 전에 대칭 키 암호화를 사용하여 이 데이터를 암호화해야 합니다.

디코딩을 위해 비디오를 암호화하기 위해 소프트웨어 디코더는 다음 인터페이스를 사용합니다.

  • ID3D11VideoDecoder. 액셀러레이터라고도 하는 디코더 디바이스를 나타냅니다.
  • ID3D11CryptoSession. 암호화 키를 제공하는 암호화 세션을 나타냅니다.
  • ID3D11AuthenticatedChannel. 소프트웨어 디코더가 암호화 세션을 디코더와 연결할 수 있도록 하는 인증된 채널을 나타냅니다.

direct3d9 디코딩 인터페이스를 보여 주는 다이어그램

이러한 모든 인터페이스는 다음과 같이 Direct3D11 디바이스에서 가져옵니다.

인터페이스 만들기
ID3D11VideoDecoder ID3D11VideoDevice::CreateVideoDecoder를 호출합니다. 디코더 형식은 프로필 GUID로 식별됩니다.
ID3D11CryptoSession ID3D11VideoDevice::CreateCryptoSession을 호출합니다.
ID3D11AuthenticatedChannel ID3D11VideoDevice::CreateAuthenticatedChannel을 호출합니다.

 

참고

ID3D11VideoDevice 인터페이스에 대한 포인터를 가져오려면 ID3D11Device 인터페이스에서 QueryInterface를 호출합니다.

 

인증된 채널은 소프트웨어 디코더와 드라이버 간에 신뢰할 수 있는 통신 채널을 제공합니다. 통신 채널은 다음과 같이 작동합니다.

  • 드라이버는 Microsoft에서 루트 인증서를 서명하는 X.509 인증서 체인을 제공합니다.
  • 인증서에는 드라이버에 대한 RSA 공개 키가 포함되어 있습니다.
  • 소프트웨어 디코더는 공개 키를 사용하여 드라이버에 128비트 AES 세션 키를 보냅니다.
  • 소프트웨어 디코더는 인증된 채널에 쿼리 및 명령을 보냅니다.
  • 세션 키는 쿼리 및 명령에 대한 MAC(메시지 인증 코드)를 계산하는 데 사용됩니다. 드라이버는 MAC를 사용하여 쿼리/명령 데이터의 무결성을 확인하고 소프트웨어 디코더는 이를 사용하여 드라이버의 응답 데이터의 무결성을 확인합니다.

디코더에 대한 압축된 비디오 버퍼 암호화

다음은 암호화 및 디코딩 프로세스에 대한 개략적인 개요입니다.

  1. 소프트웨어 디코더는 비디오 원본에서 암호화된 데이터 스트림을 받습니다. 디코더는 이 스트림의 암호를 해독합니다.

  2. 소프트웨어 디코더는 암호화 세션과 세션 키를 협상합니다.

  3. 소프트웨어 디코더는 인증된 채널을 사용하여 암호화 세션을 디코더 디바이스와 연결합니다.

  4. 소프트웨어 디코더는 압축된 데이터를 디코더 디바이스(액셀러레이터)에서 가져오는 버퍼에 넣습니다. 보호된 콘텐츠의 경우 소프트웨어 인코더는 암호화에 세션 키를 사용하여 버퍼에 포함된 데이터를 암호화합니다.

    참고

    일부 드라이버는 암호화를 위해 세션 키 대신 콘텐츠 키를 사용합니다. 콘텐츠 키가 한 프레임에서 다음 프레임으로 변경 될 수 있습니다.

     

  5. 디코더는 암호화된 압축 버퍼를 가속기로 제출합니다. AES-CTR의 경우 디코더는 초기화 벡터도 전달합니다. 콘텐츠 키를 사용하는 경우 디코더는 세션 키를 사용하여 암호화된 콘텐츠 키를 전달합니다.

Direct3D11은 128비트 AES-CTR에 대한 표준 지원을 제공하지만 추가 암호화 유형으로 확장되도록 설계되었습니다.

다음 5개 섹션에서는 더 자세한 단계를 제공합니다.

1. 드라이버의 콘텐츠 보호 기능 쿼리

암호화를 적용하기 전에 드라이버의 콘텐츠 보호 기능을 가져옵니다.

  1. ID3D11Device 인터페이스에 대한 포인터를 가져옵니다.
  2. ID3D11VideoDevice 인터페이스에 대해 QueryInterface를 호출합니다.
  3. ID3D11VideoDevice::GetContentProtectionCaps를 호출합니다. 이 메서드는 드라이버의 콘텐츠 보호 기능으로 D3D11_VIDEO_CONTENT_PROTECTION_CAPS 구조를 채웁니다.

특히 다음 기능을 찾습니다.

  • Caps 멤버에 D3D11_CONTENT_PROTECTION_CAPS_SOFTWARE 또는 D3D11_CONTENT_PROTECTION_CAPS_HARDWARE 플래그가 포함된 경우 드라이버는 암호화를 수행할 수 있습니다.
  • Caps 멤버에 D3D11_CONTENT_PROTECTION_CAPS_CONTENT_KEY 플래그가 포함된 경우 드라이버는 암호 해독을 위해 별도의 콘텐츠 키를 사용합니다.
  • ID3D11VideoDevice::CheckCryptoKeyExchange를 호출하여 드라이버가 세션 키 생성을 지원하는 키 교환 유형을 결정합니다.

Caps 멤버에 추가 기능이 표시됩니다.

2. 인증된 채널 구성

다음 단계는 인증된 채널을 구성하는 것입니다.

  1. ID3D11VideoDevice::CreateAuthenticatedChannel을 호출하여 인증된 채널을 만듭니다. ChannelType 매개 변수의 경우 드라이버의 기능과 일치하는 채널 형식을 지정합니다.

    • D3D11_AUTHENTICATED_CHANNEL_DRIVER_SOFTWARE 채널 형식은 D3D11_CONTENT_PROTECTION_CAPS_SOFTWARE 해당합니다.
    • D3D11_AUTHENTICATED_CHANNEL_DRIVER_HARDWARE 채널 형식은 D3D11_CONTENT_PROTECTION_CAPS_HARDWARE 해당합니다.

    CreateAuthenticatedChannel 메서드는 ID3D11AuthenticatedChannel 인터페이스에 대한 포인터를 반환합니다.

  2. ID3D11AuthenticatedChannel::GetCertificateSize를 호출하여 드라이버의 X.509 인증서 크기를 가져옵니다. 필요한 크기의 버퍼를 할당합니다.

  3. ID3D11AuthenticatedChannel::GetCertificate를 호출하여 인증서를 가져옵니다. 메서드는 이전 단계에서 할당된 버퍼에 인증서를 복사합니다.

  4. 드라이버의 인증서가 Microsoft에서 서명되었으며 해지되지 않은지 확인합니다.

  5. 인증서에서 공개 키를 가져옵니다.

  6. 임의의 RSA 세션 키를 생성합니다. 이 세션 키는 인증된 채널로 전송되는 데이터에 서명하는 데 사용됩니다. 드라이버의 공개 키를 사용하여 세션 키를 암호화합니다.

  7. ID3D11VideoContext::NegotiateAuthenticatedChannelKeyExchange를 호출하여 암호화된 세션 키를 드라이버에 보냅니다.

  8. 다음과 같이 보안 채널을 초기화합니다.

    1. 설명서에 설명된 대로 D3D11_AUTHENTICATED_CONFIGURE_INITIALIZE_INPUT 구조를 입력합니다.
    2. 인증된 채널 명령 보내기 섹션에 설명된 대로 ID3D11VideoContext::ConfigureAuthenticatedChannel을 호출하여 D3D11_AUTHENTICATED_CONFIGURE_INITIALIZE_INPUT 명령을 보냅니다. 이 명령에는 인증된 채널로 전송되는 명령 및 쿼리에 대한 시작 시퀀스 번호가 포함됩니다.
  9. 인증된 채널 쿼리 보내기 섹션에 설명된 대로 인증된 채널에 D3D11_AUTHENTICATED_QUERY_CHANNEL_TYPE쿼리를 전송하여 채널 유형을 확인합니다. 채널 형식이 CreateAuthenticatedChannel 메서드에서 지정한 것과 일치하는지 확인합니다.

3. 암호화 세션 구성

다음으로, 암호화 세션을 구성하고 세션 키를 설정합니다.

  1. ID3D11VideoDevice::CreateCryptoSession을 호출하여 암호화 세션을 만듭니다. 이 메서드는 ID3D11CryptoSession 인터페이스에 대한 포인터를 반환합니다.
  2. ID3D11CryptoSession::GetCertificateSize를 호출하여 드라이버의 X.509 인증서 크기를 가져옵니다. 필요한 크기의 버퍼를 할당합니다.
  3. ID3D11CryptoSession::GetCertificate를 호출하여 인증서를 가져옵니다. 메서드는 이전 단계에서 할당된 버퍼에 인증서를 복사합니다.
  4. 드라이버의 인증서가 Microsoft에서 서명되었으며 해지되지 않은지 확인합니다.
  5. 인증서에서 공개 키를 가져옵니다.
  6. 임의의 RSA 세션 키를 생성합니다. 인증된 채널 세션 키와는 별도의 세션 키입니다. 드라이버의 공개 키를 사용하여 세션 키를 암호화합니다.
  7. ID3D11VideoContext::NegotiateCryptoSessionKeyExchange를 호출하여 암호화된 세션 키를 드라이버에 보냅니다.
  8. 콘텐츠 보호 기능에 3D11_CONTENT_PROTECTION_CAPS_CONTENT_KEY 포함된 경우 임의의 RSA 콘텐츠 키를 만듭니다. 디코딩 프로세스의 뒷부분에서 사용됩니다.

4. 디코더를 암호화 세션과 연결

다음으로, 다음과 같이 디코더 디바이스를 Direct3D11 디바이스 및 암호화 세션과 연결합니다.

  1. 인증된 채널에 D3D11_AUTHENTICATED_QUERY_DEVICE_HANDLE 쿼리를 보내 Direct3D11 디바이스에 대한 핸들을 가져옵니다.
  2. 다음 정보를 사용하여 D3D11_AUTHENTICATED_CONFIGURE_CRYPTO_SESSION_INPUT 구조를 채웁니다.
  3. ID3D11VideoContext::ConfigureAuthenticatedChannel을 호출하여 인증된 채널에 D3D11_AUTHENTICATED_CONFIGURE_CRYPTO_SESSION 명령을 보냅니다.

다음 다이어그램에서는 핸들 교환을 보여 줍니다.

dxva 디코더가 암호화 세션과 연결되는 방법을 보여 주는 다이어그램입니다.

이제 소프트웨어 디코더가 암호화 세션 키를 사용하여 압축된 비디오 버퍼를 암호화할 수 있습니다. 압축된 각 버퍼에는 D3D11_VIDEO_DECODER_BUFFER_DESC 구조체의 pIV 멤버에 지정된 자체 IV(초기화 벡터)가 있습니다.

인증된 채널 명령 보내기

인증된 채널을 구성하고 다양한 콘텐츠 보호를 설정하기 위해 명령 집합이 정의됩니다. 명령 목록은 콘텐츠 보호 명령을 참조하세요.

인증된 채널에 명령을 보내려면 다음 단계를 수행합니다.

  1. 입력 데이터 구조를 입력합니다. 이 데이터 구조는 항상 D3D11_AUTHENTICATED_CONFIGURE_INPUT 구조와 추가 필드입니다. 다음 표와 같이 D3D11_AUTHENTICATED_CONFIGURE_INPUT 구조를 채웁니다.
멤버 Description
omac 지금은 이 필드를 건너뜁니다.
ConfigureType 명령을 식별하는 GUID입니다. 명령 목록은 콘텐츠 보호 명령을 참조하세요.
hChannel 인증된 채널에 대한 핸들입니다.
SequenceNumber 시퀀스 번호입니다. 첫 번째 시퀀스 번호는 D3D11_AUTHENTICATED_CONFIGURE_INITIALIZE 명령을 전송하여 지정됩니다. 다른 명령을 보낼 때마다 이 숫자를 1씩 증분합니다. 시퀀스 번호는 재생 공격을 방지합니다. 참고: 두 개의 개별 시퀀스 번호가 사용되며, 하나는 명령에, 다른 하나는 쿼리용으로 사용됩니다.
  1. 입력 구조체의 omac 멤버 다음에 나타나는 데이터 블록에 대한 OMAC 태그를 계산합니다. 그런 다음 이 태그 값을 omac 멤버에 복사합니다.
  2. ID3D11VideoContext::ConfigureAuthenticatedChannel을 호출합니다.
  3. 드라이버는 명령의 출력을 D3D11_AUTHENTICATED_CONFIGURE_OUTPUT 구조체에 배치합니다.
  4. 출력 구조체의 omac 멤버 다음에 나타나는 데이터 블록에 대한 OMAC 태그를 계산합니다. 이를 omac 멤버의 값과 비교합니다. 일치하지 않으면 실패합니다.
  5. 출력 구조의 ConfigureType, hChannelSequenceNumber 멤버의 값을 해당 멤버의 값과 비교합니다. 일치하지 않으면 실패합니다.
  6. 다음 명령에 대한 시퀀스 번호를 증분합니다.

인증된 채널 쿼리 보내기

인증된 채널에 대한 정보를 검색하기 위한 쿼리 집합이 정의됩니다. 쿼리 목록은 콘텐츠 보호 쿼리를 참조하세요.

인증된 채널에 명령을 보내려면 다음 단계를 수행합니다.

  1. 입력 데이터 구조를 입력합니다. 이 데이터 구조는 항상 D3D11_AUTHENTICATED_QUERY_INPUT 구조이며 추가 필드가 뒤따를 수 있습니다. 다음 표와 같이 D3D11_AUTHENTICATED_QUERY_INPUT 구조를 채웁니다.
멤버 Description
QueryType 쿼리를 식별하는 GUID입니다. 쿼리 목록은 콘텐츠 보호 쿼리를 참조하세요.
hChannel 인증된 채널에 대한 핸들입니다.
SequenceNumber 시퀀스 번호입니다. 첫 번째 시퀀스 번호는 D3D11_AUTHENTICATED_CONFIGURE_INITIALIZE 명령을 전송하여 지정됩니다. 다른 쿼리를 보낼 때마다 이 숫자를 1씩 증분합니다. 시퀀스 번호는 재생 공격을 방지합니다. 참고: 두 개의 개별 시퀀스 번호가 사용되며, 하나는 명령에, 다른 하나는 쿼리용으로 사용됩니다.
  1. ID3D11VideoContext::QueryAuthenticatedChannel을 호출합니다.
  2. 드라이버는 쿼리의 출력을 D3D11_AUTHENTICATED_QUERY_OUTPUT 구조에 배치합니다. 이 구조체 뒤에는 쿼리 형식에 따라 추가 필드가 잇습니다.
  3. 출력 구조체의 omac 멤버 다음에 나타나는 데이터 블록에 대한 OMAC 태그를 계산합니다. 이를 omac 멤버의 값과 비교합니다. 일치하지 않으면 실패합니다.
  4. 출력 구조의 ConfigureType, hChannelSequenceNumber 멤버의 값을 해당 멤버의 값과 비교합니다. 일치하지 않으면 실패합니다.
  5. 다음 쿼리의 시퀀스 번호를 증분합니다.

Direct3D 11 비디오 API