使用 D3D11 影片 GPU-Based 內容保護
本主題描述圖形驅動程式可以提供的視訊內容保護功能。
簡介
下圖顯示受保護視訊內容如何透過管線轉譯的簡化檢視。
注意
此圖未描述 受保護的媒體路徑 (PMP) 。 此處顯示的資料流程可能會發生在 PMP 進程或應用程式進程內。
解碼器會從外部來源接收加密、壓縮的視訊資料。 它也假設解碼器也會收到密碼編譯金鑰來解密此資料。 本主題不會描述影片來源與解碼器之間的金鑰交換,但 PMP 會定義一個可能的機制。 此階段未涉及 GPU。
針對硬體加速解碼,軟體解碼器會將壓縮的視訊內容傳遞至 GPU。 為了保護此內容,解碼器會在將資料傳遞至硬體加速器之前,先使用 AES-CTR 重新加密資料。 解碼器和圖形驅動程式之間定義了金鑰交換器制。
解碼的視訊畫面會儲存在視訊記憶體中,通常是在清除中。 此時會處理框架,然後呈現。 簡報有兩個主要選項。
- 使用 D3D9 API 時,可以使用硬體重迭來呈現畫面。 D3D11 不支援過度硬體。 如需詳細資訊,請參閱 硬體重迭支援。
- 您可以使用共用介面,透過桌面視窗管理 (DWM) 來呈現框架。
最後一個步驟是在監視器上顯示框架,這可能需要圖形卡與顯示裝置之間的連結保護。 連結保護的範例是 High-Bandwidth Digital Content Protection (HDCP) 。 連結保護是使用 輸出保護管理員 設定, (OPM) 。 本主題未描述 OPM;如需詳細資訊,請參閱 使用輸出保護管理員。
解碼程式概觀
在硬體加速解碼期間,軟體解碼器必須將壓縮的視訊資料傳遞至圖形卡。 針對進階內容,此資料通常必須先使用對稱金鑰加密來加密,才能傳送至 GPU。
若要加密影片以進行解碼,軟體解碼器會使用下列介面:
- ID3D11VideoDecoder。 表示解碼器裝置,也稱為加速器。
- ID3D11CryptoSession。 表示提供加密金鑰的密碼編譯會話。
- ID3D11AuthenticatedChannel。 表示已驗證的通道,可讓軟體解碼器將密碼編譯會話與解碼器產生關聯。
所有這些介面都是從 Direct3D11 裝置取得,如下所示:
注意
若要取得ID3D11VideoDevice介面的指標,請在ID3D11Device介面上呼叫QueryInterface。
已驗證的通道會在軟體解碼器和驅動程式之間提供信任的通道。 通道的運作方式如下:
- 驅動程式提供 X.509 憑證鏈結,其根憑證是由 Microsoft 簽署。
- 憑證包含驅動程式的 RSA 公開金鑰。
- 軟體解碼器會使用公開金鑰來傳送驅動程式 128 位 AES 工作階段金鑰。
- 軟體解碼器會將查詢和命令傳送至已驗證的通道。
- 工作階段金鑰是用來計算查詢和命令 (MAC) 訊息驗證碼。 驅動程式會使用 MAC 來驗證查詢/命令資料的完整性,而軟體解碼器會使用它們來驗證驅動程式回應資料的完整性。
加密解碼器的壓縮視訊緩衝區
以下是加密和解碼程式的高階概觀:
軟體解碼器會從視訊來源接收加密資料的資料流程。 解碼器會將此資料流程解密。
軟體解碼器會與密碼編譯會話交涉工作階段金鑰。
軟體解碼器會使用已驗證的通道,將密碼編譯會話與解碼器裝置產生關聯。
軟體解碼器會將壓縮的資料放在從解碼器裝置取得的緩衝區中, (加速器) 。 針對受保護的內容,軟體編碼器會使用工作階段金鑰來加密放入緩衝區的資料。
注意
某些驅動程式會使用內容金鑰,而不是工作階段金鑰進行加密。 內容索引鍵可能會從一個畫面變更為下一個畫面。
解碼器會將加密的壓縮緩衝區提交至加速器。 針對 AES-CTR,解碼器也會傳遞初始化向量。 如果使用內容金鑰,解碼器會傳遞內容金鑰,並使用工作階段金鑰加密。
Direct3D11 具有 128 位 AES-CTR 的標準支援,但專為擴充至其他加密類型而設計。
接下來五節提供更詳細的步驟。
1.查詢驅動程式的內容保護功能
嘗試套用加密之前,請先取得驅動程式的內容保護功能。
- 取得 ID3D11Device 介面的指標。
- 呼叫ID3D11VideoDevice介面的QueryInterface。
- 呼叫 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.設定已驗證通道
下一個步驟是設定已驗證的通道。
呼叫 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介面的指標。
呼叫 ID3D11AuthenticatedChannel::GetCertificateSize 以取得驅動程式 X.509 憑證的大小。 配置所需大小的緩衝區。
呼叫 ID3D11AuthenticatedChannel::GetCertificate 以取得憑證。 方法會將憑證複製到上一個步驟中配置的緩衝區。
確認驅動程式的憑證已由 Microsoft 簽署,且尚未撤銷。
從憑證取得公開金鑰。
產生隨機 RSA 工作階段金鑰。 此工作階段金鑰可用來簽署傳送至已驗證通道的資料。 使用驅動程式的公開金鑰來加密工作階段金鑰。
呼叫 ID3D11VideoCoNtext::NegotiateAuthenticatedChannelKeyExchange 以將加密的工作階段金鑰傳送至驅動程式。
初始化安全通道,如下所示:
- 如檔所述,填入 D3D11_AUTHENTICATED_CONFIGURE_INITIALIZE_INPUT 結構。
- 呼叫ID3D11VideoCoNtext::ConfigureAuthenticatedChannel,以傳送D3D11_AUTHENTICATED_CONFIGURE_INITIALIZE_INPUT命令,如傳送已驗證通道命令一節中所述。 此命令包含傳送至已驗證通道之命令和查詢的起始序號。
如傳送已驗證通道查詢一節所述,將D3D11_AUTHENTICATED_QUERY_CHANNEL_TYPE查詢傳送至已驗證的通道,以驗證通道類型。 檢查通道類型是否符合您在 CreateAuthenticatedChannel 方法中指定的專案。
3.設定密碼編譯會話
接下來,設定密碼編譯會話並建立工作階段金鑰。
- 呼叫 ID3D11VideoDevice::CreateCryptoSession 以建立密碼編譯會話。 這個方法會傳回 ID3D11CryptoSession 介面的指標。
- 呼叫 ID3D11CryptoSession::GetCertificateSize 以取得驅動程式 X.509 憑證的大小。 配置所需大小的緩衝區。
- 呼叫 ID3D11CryptoSession::GetCertificate 以取得憑證。 方法會將憑證複製到上一個步驟中配置的緩衝區。
- 確認驅動程式的憑證已由 Microsoft 簽署,且尚未撤銷。
- 從憑證取得公開金鑰。
- 產生隨機 RSA 工作階段金鑰。 這是與已驗證通道工作階段金鑰不同的工作階段金鑰。 使用驅動程式的公開金鑰來加密工作階段金鑰。
- 呼叫 ID3D11VideoCoNtext::NegotiateCryptoSessionKeyExchange 以將加密的工作階段金鑰傳送至驅動程式。
- 如果內容保護功能包含 3D11_CONTENT_PROTECTION_CAPS_CONTENT_KEY,請建立隨機 RSA 內容金鑰。 稍後會在解碼程式中使用。
4.將解碼器與密碼編譯會話產生關聯
接下來,將解碼器裝置與 Direct3D11 裝置和密碼編譯會話產生關聯,如下所示:
- 藉由將 D3D11_AUTHENTICATED_QUERY_DEVICE_HANDLE 查詢傳送至已驗證通道,以取得 Direct3D11 裝置的控制碼。
- 使用下列資訊填入 D3D11_AUTHENTICATED_CONFIGURE_CRYPTO_SESSION_INPUT 結構:
- 將 DecodeHandle 成員設定為從 ID3D11VideoDecoder::GetDriverHandle傳回的控制碼。
- 將 CryptoSessionHandle 成員設定為從 ID3D11CryptoSession::GetCryptoSessionHandle傳回的控制碼。
- 將 DeviceHandle 成員設定為 Direct3D11 裝置控制碼。
- 呼叫 ID3D11VideoCoNtext::ConfigureAuthenticatedChannel ,將 D3D11_AUTHENTICATED_CONFIGURE_CRYPTO_SESSION 命令傳送至已驗證的通道。
下圖說明控制碼的交換:
軟體解碼器現在可以使用密碼編譯工作階段金鑰來加密壓縮的視訊緩衝區。 每個壓縮的緩衝區都會有自己的初始化向量 (IV) 在D3D11_VIDEO_DECODER_BUFFER_DESC結構的pIV成員中指定。
傳送已驗證的通道命令
系統會定義一組命令來設定已驗證的通道,以及設定各種內容保護。 如需命令清單,請參閱 Content Protection 命令。
若要將命令傳送至已驗證的通道,請執行下列步驟。
- 填入輸入資料結構。 此資料結構一律是 D3D11_AUTHENTICATED_CONFIGURE_INPUT 結構,後面接著其他欄位。 填入 D3D11_AUTHENTICATED_CONFIGURE_INPUT 結構,如下表所示。
member | 描述 |
---|---|
omac | 目前請略過此欄位。 |
ConfigureType | 識別命令的 GUID。 如需命令清單,請參閱 Content Protection 命令。 |
hChannel | 已驗證通道的控制碼。 |
SequenceNumber | 序號。 第一個序號是藉由傳送 D3D11_AUTHENTICATED_CONFIGURE_INITIALIZE 命令來指定。 每次傳送另一個命令時,請將此數位遞增 1。 序號可防範重新執行攻擊。
注意: 使用兩個不同的序號,一個用於命令,另一個用於查詢。 |
- 計算出現在輸入結構 omac 成員之後之資料區塊的 OMAC 標籤。 然後將此標籤值複製到 omac 成員。
- 呼叫 ID3D11VideoCoNtext::ConfigureAuthenticatedChannel。
- 驅動程式會將命令的輸出放在 D3D11_AUTHENTICATED_CONFIGURE_OUTPUT 結構中。
- 計算輸出結構 omac 成員之後所出現資料區塊的 OMAC 標籤。 將此與 omac 成員的值進行比較。 如果不符合,則失敗。
- 比較輸出結構中 ConfigureType、 hChannel和 SequenceNumber 成員的值,與這些成員的值進行比較。 如果不符合,則失敗。
- 遞增下一個命令的序號。
傳送已驗證的通道查詢
系統會定義一組查詢,以擷取已驗證通道的相關資訊。 如需查詢清單,請參閱 內容保護查詢。
若要將命令傳送至已驗證的通道,請執行下列步驟。
- 填入輸入資料結構。 此資料結構一律是 D3D11_AUTHENTICATED_QUERY_INPUT 結構,後面可能接著其他欄位。 填入 D3D11_AUTHENTICATED_QUERY_INPUT 結構,如下表所示。
member | 描述 |
---|---|
QueryType | 識別查詢的 GUID。 如需查詢清單,請參閱 內容保護查詢。 |
hChannel | 已驗證通道的控制碼。 |
SequenceNumber | 序號。 第一個序號是藉由傳送 D3D11_AUTHENTICATED_CONFIGURE_INITIALIZE 命令來指定。 每次傳送另一個查詢時,請將此數位遞增 1。 序號可防範重新執行攻擊。
注意: 使用兩個不同的序號,一個用於命令,另一個用於查詢。 |
- 呼叫 ID3D11VideoCoNtext::QueryAuthenticatedChannel。
- 驅動程式會將查詢的輸出放在 D3D11_AUTHENTICATED_QUERY_OUTPUT 結構中。 此結構後面接著其他欄位,視查詢類型而定。
- 計算輸出結構 omac 成員之後所出現資料區塊的 OMAC 標籤。 將此與 omac 成員的值進行比較。 如果不符合,則失敗。
- 比較輸出結構中 ConfigureType、 hChannel和 SequenceNumber 成員的值,與這些成員的值進行比較。 如果不符合,則失敗。
- 遞增下一個查詢的序號。
相關主題