IDirect3DCryptoSession9
COM公式ドキュメント
暗号化セッションを表します。このインターフェースへのポインターを取得するには、IDirect3DDevice9Video::CreateCryptoSession を呼び出します。
メソッド 9
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
ドライバーの証明書チェーンのサイズを取得します。(IDirect3DCryptoSession9.GetCertificateSize)
| pCertificateSize | DWORD* | inout | 証明書チェーンのサイズをバイト単位で受け取ります。 |
戻り値
このメソッドが成功した場合は S_OK を返します。それ以外の場合は HRESULT エラーコードを返します。
解説(Remarks)
証明書を取得するには、IDirect3DCryptoSession9::GetCertificate を呼び出します。
ドライバーの証明書チェーンを取得します。(IDirect3DCryptoSession9.GetCertificate)
| CertifacteSize | DWORD | in | ppCertificate 配列のサイズをバイト単位で指定します。証明書チェーンのサイズを取得するには、IDirect3DCryptoSession9::GetCertificateSize を呼び出します。 |
| ppCertificate | BYTE* | inout | ドライバーの証明書チェーンを受け取るバイト配列へのポインターです。呼び出し元が配列を割り当てる必要があります。 |
戻り値
このメソッドが成功した場合は S_OK を返します。それ以外の場合は HRESULT エラーコードを返します。
解説(Remarks)
標準の鍵交換メカニズムでは、ドライバーの Output Protection Manager (OPM) 証明書が使用されます。これは X.509 証明書です。鍵交換の種類は、IDirect3DDevice9Video::GetContentProtectionCaps メソッドが返す機能情報に示されます。鍵交換メカニズムは、D3DCONTENTPROTECTIONCAPS 構造体の KeyExchangeType メンバーで指定されます。値が D3DKEYEXCHANGE_RSAES_OAEP の場合、X.509 証明書が使用されます。
他の種類の鍵交換の場合、ドライバーは別の種類の証明書を使用することもあれば、証明書を提供しないこともあります。
暗号化セッションのセッション鍵を確立します。
| DataSize | DWORD | in | pData バイト配列のサイズをバイト単位で指定します。 |
| pData | void* | inout | 暗号化されたセッション鍵を格納するバイト配列へのポインターです。 |
戻り値
このメソッドが成功した場合は S_OK を返します。それ以外の場合は HRESULT エラーコードを返します。
解説(Remarks)
使用する鍵交換メカニズムを調べるには、IDirect3DDevice9Video::GetContentProtectionCaps メソッドを呼び出します。鍵交換メカニズムは、D3DCONTENTPROTECTIONCAPS 構造体の KeyExchangeType メンバーで指定されます。値が D3DKEYEXCHANGE_RSAES_OAEP の場合は、RSA Encryption Scheme - Optimal Asymmetric Encryption Padding (RSAES-OAEP) を使用してセッション鍵を暗号化します。この暗号化された暗号文を pData パラメーターで渡します。
鍵交換の種類が D3DKEYEXCHANGE_DXVA の場合は、セッション鍵を確立するためにこのメソッドを呼び出さないでください。代わりに、DirectX Video Acceleration 2 (DXVA-2) デコードで定義されている鍵交換メカニズムを使用します。
ドライバーは独自の鍵交換メカニズムを使用する場合もあります。
保護されたサーフェスから暗号化されたデータを読み取ります。(IDirect3DCryptoSession9.EncryptionBlt)
| pSrcSurface | IDirect3DSurface9* | in | 保護されたサーフェスへのポインターです。 |
| pDstSurface | IDirect3DSurface9* | in | 暗号化されたデータを受け取るサーフェスへのポインターです。 |
| DstSurfaceSize | DWORD | in | pDstSurface が指すサーフェスメモリのサイズをバイト単位で指定します。サイズは、ドライバー機能構造体の BlockAlignmentSize の値に合わせて整列されている必要があります。「解説」を参照してください。 |
| pIV | void* | inout | 初期化ベクトル (IV) を受け取るバッファーへのポインターです。このバッファーは呼び出し元が割り当てますが、IV はドライバーが生成します。 暗号化の種類が D3DCRYPTOTYPE_AES128_CTR (128 ビット AES-CTR) の場合、pIV は D3DAES_CTR_IV 構造体を指します。ドライバーは最初の IV を生成するときに、構造体を乱数で初期化します。以降の各 IV については、ドライバーは構造体の IV メンバーをインクリメントするだけで、値が常に増加するようにします。この手順により、同じ鍵ペアで同じ IV が 2 回以上使用されないことをアプリケーションが検証できます。 他の暗号化の種類の場合、別の構造体が使用されることもあれば、暗号化で IV が使用されないこともあります。 |
戻り値
このメソッドが成功した場合は S_OK を返します。それ以外の場合は HRESULT エラーコードを返します。
解説(Remarks)
ドライバーがこのメソッドをサポートしている場合、IDirect3DDevice9Video::GetContentProtectionCaps メソッドが返す機能構造体に D3DCPCAPS_ENCRYPTEDREADBACK フラグを設定します。
ドライバーが D3DCPCAPS_ENCRYPTEDREADBACKKEY 機能フラグを設定している場合、ドライバーはデータの暗号化に別個の鍵を使用することを意味します。この鍵を取得するには、IDirect3DCryptoSession9::GetEncryptionBltKey メソッドを呼び出します。それ以外の場合、ドライバーはセッション鍵を使用してデータを暗号化します。
宛先サーフェス (pDstSurface) は次のように割り当てます。
- IDirect3DCryptoSession9::GetSurfacePitch を呼び出して、保護されたサーフェスのストライドを取得します。
- GetContentProtectionCaps メソッドを呼び出して、D3DCONTENTPROTECTIONCAPS 構造体の BufferAlignmentStart メンバーと BlockAlignmentSize メンバーの値を取得します。
- サーフェスメモリの最小サイズを SysMemSize = 保護されたサーフェスのストライド × 保護されたサーフェスの高さ として計算します。
- BufferAlignmentStart と BlockAlignmentSize の値に対応するためのパディングを追加します。
- システムメモリに、サイズが SysMemSize (パディングを含む) に等しいバッファーを割り当てます。
- システムメモリバッファーのアドレスが BufferAlignmentStart の値に整列していない場合は、バッファーの先頭からのオフセットとなるメモリ整列済みポインターを計算します。
- IDirect3DDevice9Ex::CreateOffscreenPlainSurfaceEx を呼び出して宛先サーフェスを作成します。メモリ整列済みポインターを共有リソースハンドル (pSharedHandle) として渡します。
- サブ矩形や部分的に暗号化されたサーフェスを読み戻すことはできません。
- 保護されたサーフェスは、オフスクリーンプレーンサーフェスまたはレンダーターゲットのいずれかである必要があります。
- 宛先サーフェスは、前述のとおり適切な整列で作成されたシステムメモリサーフェスである必要があります。
- 保護されたサーフェスをマルチサンプリングすることはできません。
- このメソッドは、ストレッチや色空間変換をサポートしません。
保護されたサーフェスに暗号化されたデータを書き込みます。(IDirect3DCryptoSession9.DecryptionBlt)
| pSrcSurface | IDirect3DSurface9* | in | ソースデータを格納するサーフェスへのポインターです。 |
| pDstSurface | IDirect3DSurface9* | in | 暗号化されたデータが書き込まれる保護されたサーフェスへのポインターです。 |
| SrcSurfaceSize | DWORD | in | pSrcSurface が指すサーフェスメモリのサイズをバイト単位で指定します。サイズは、ドライバー機能構造体の BlockAlignmentSize の値に合わせて整列されている必要があります。「解説」を参照してください。 |
| pEncryptedBlockInfo | D3DENCRYPTED_BLOCK_INFO* | inout | D3DENCRYPTED_BLOCK_INFO 構造体へのポインター、または NULL です。 ドライバーが部分的に暗号化されたバッファーをサポートしている場合、pEncryptedBlockInfo はバッファーのどの部分が暗号化されているかを示します。サーフェス全体が暗号化されている場合は、このパラメーターを NULL に設定します。 ドライバーが部分的に暗号化されたバッファーをサポートしているかどうかを確認するには、IDirect3DDevice9Video::GetContentProtectionCaps を呼び出して、D3DCPCAPS_PARTIALDECRYPTION 機能フラグを確認します。ドライバーが部分的に暗号化されたバッファーをサポートしていない場合は、このパラメーターを NULL に設定します。 |
| pContentKey | void* | inout | コンテンツ暗号化鍵を格納するバッファーへのポインター、または NULL です。ドライバーがコンテンツ鍵の使用をサポートしているかどうかを照会するには、IDirect3DDevice9Video::GetContentProtectionCaps を呼び出して、D3DCPCAPS_CONTENTKEY 機能フラグを確認します。 ドライバーがコンテンツ鍵をサポートしている場合は、コンテンツ鍵を使用してサーフェスを暗号化します。コンテンツ鍵をセッション鍵で暗号化し、その結果の暗号文を pContentKey に格納します。ドライバーがコンテンツ鍵をサポートしていない場合は、セッション鍵を使用してサーフェスを暗号化し、pContentKey を NULL に設定します。 |
| pIV | void* | inout | 初期化ベクトル (IV) を格納するバッファーへのポインターです。 暗号化の種類が D3DCRYPTOTYPE_AES128_CTR の場合、バッファーは D3DAES_CTR_IV 構造体です。呼び出し元が構造体を割り当てて IV を生成します。最初の IV を生成するときは、構造体を乱数で初期化します。以降の各 IV については、構造体の IV メンバーをインクリメントするだけで、値が常に増加するようにします。この手順により、同じ鍵ペアで同じ IV が 2 回以上使用されないことをドライバーが検証できます。 他の暗号化の種類の場合、別の構造体が使用されることもあれば、暗号化で IV が使用されないこともあります。 |
戻り値
このメソッドが成功した場合は S_OK を返します。それ以外の場合は HRESULT エラーコードを返します。
解説(Remarks)
すべてのハードウェアやドライバーが、すべての暗号化タイプに対してこの機能をサポートしているわけではありません。
ソースサーフェスは、適切な整列制限を満たして作成されたシステムメモリサーフェスである必要があります。バッファーは、保護されたサーフェスのピッチと高さに加えて、開始整列制限とブロック転送サイズに対応するためのパディングを収容できる十分な大きさである必要があります。
具体的には、ソースサーフェスを次のように割り当てます。
- IDirect3DCryptoSession9::GetSurfacePitch を呼び出して、保護されたサーフェスのストライドを取得します。
- IDirect3DDevice9Video::GetContentProtectionCaps メソッドを呼び出して、D3DCONTENTPROTECTIONCAPS 構造体の BufferAlignmentStart メンバーと BlockAlignmentSize メンバーの値を取得します。
- サーフェスメモリの最小サイズを SysMemSize = 保護されたサーフェスのストライド × 保護されたサーフェスの高さ として計算します。
- BufferAlignmentStart と BlockAlignmentSize の値に対応するためのパディングを追加します。
- システムメモリに、サイズが SysMemSize (パディングを含む) に等しいバッファーを割り当てます。
- システムメモリバッファーのアドレスが BufferAlignmentStart の値に整列していない場合は、バッファーの先頭からのオフセットとなるメモリ整列済みポインターを計算します。
- IDirect3DDevice9Ex::CreateOffscreenPlainSurfaceEx を呼び出してソースサーフェスを作成します。メモリ整列済みポインターを共有リソースハンドル (pSharedHandle) として渡します。
このメソッドは、サーフェスのサブ矩形への書き込みをサポートしません。
保護されたサーフェスのストライドを取得します。
| pSrcSurface | IDirect3DSurface9* | in | 保護されたサーフェスへのポインターです。 |
| pSurfacePitch | DWORD* | inout | ストライドをバイト単位で受け取ります。 |
戻り値
このメソッドが成功した場合は S_OK を返します。それ以外の場合は HRESULT エラーコードを返します。
解説(Remarks)
保護されたサーフェスはロックできないため、このメソッドはサーフェスをロックせずにサーフェスのストライドを取得する方法を提供します。
セッション鍵の更新に使用できる乱数を取得します。(IDirect3DCryptoSession9.StartSessionKeyRefresh)
| pRandomNumber | void* | inout | 乱数を受け取るバイト配列へのポインターです。 |
| RandomNumberSize | DWORD | in | pRandomNumber 配列のサイズをバイト単位で指定します。サイズはセッション鍵のサイズと一致している必要があります。 |
戻り値
このメソッドが成功した場合は S_OK を返します。それ以外の場合は HRESULT エラーコードを返します。
解説(Remarks)
新しいセッション鍵を生成するには、以前のセッション鍵と乱数のビットごとの XOR を実行します。新しいセッション鍵は、アプリケーションが IDirect3DCryptoSession9::FinishSessionKeyRefresh を呼び出すまで有効になりません。
ドライバーがこのメソッドをサポートしている場合、ドライバーは IDirect3DDevice9Video::GetContentProtectionCaps メソッドで D3DCPCAPS_FRESHENSESSIONKEY 機能フラグを設定します。
新しいセッション鍵に切り替えます。(IDirect3DCryptoSession9.FinishSessionKeyRefresh)
戻り値
このメソッドが成功した場合は S_OK を返します。それ以外の場合は HRESULT エラーコードを返します。
解説(Remarks)
このメソッドを呼び出す前に、IDirect3DCryptoSession9::StartSessionKeyRefresh メソッドを呼び出します。StartSessionKeyRefresh メソッドはドライバーから乱数を取得し、これを使用して新しいセッション鍵を作成します。新しいセッション鍵は、アプリケーションが FinishSessionKeyRefresh を呼び出すまで有効になりません。アプリケーションが FinishSessionKeyRefresh を呼び出した後は、すべての保護されたサーフェスが新しいセッション鍵を使用して暗号化されます。
IDirect3DCryptoSession9::EncryptionBlt メソッドが返すデータを復号するために使用される暗号鍵を取得します。
| pReadbackKey | void* | inout | 鍵を受け取るバイト配列へのポインターです。鍵はセッション鍵を使用して暗号化されます。 |
| KeySize | DWORD | in | pReadbackKey 配列のサイズをバイト単位で指定します。サイズはセッション鍵のサイズと一致している必要があります。 |
戻り値
このメソッドが成功した場合は S_OK を返します。それ以外の場合は HRESULT エラーコードを返します。
解説(Remarks)
このメソッドは、ドライバーが EncryptionBlt メソッド用に別個のコンテンツ鍵を必要とする場合にのみ適用されます。ドライバーがコンテンツ鍵を必要とする場合、IDirect3DDevice9Video::GetContentProtectionCaps メソッドが返す機能構造体に D3DCPCAPS_ENCRYPTEDREADBACKKEY フラグを設定します。それ以外の場合、ドライバーはセッション鍵を使用してデータを暗号化します。
このメソッドが呼び出されるたびに、ドライバーは新しい鍵を生成します。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_IDirect3DCryptoSession9 "{FA0AB799-7A9C-48CA-8C5B-237E71A54434}" #usecom global IDirect3DCryptoSession9 IID_IDirect3DCryptoSession9 "{}" #comfunc global IDirect3DCryptoSession9_GetCertificateSize 3 var #comfunc global IDirect3DCryptoSession9_GetCertificate 4 int,var #comfunc global IDirect3DCryptoSession9_NegotiateKeyExchange 5 int,sptr #comfunc global IDirect3DCryptoSession9_EncryptionBlt 6 sptr,sptr,int,sptr #comfunc global IDirect3DCryptoSession9_DecryptionBlt 7 sptr,sptr,int,var,sptr,sptr #comfunc global IDirect3DCryptoSession9_GetSurfacePitch 8 sptr,var #comfunc global IDirect3DCryptoSession9_StartSessionKeyRefresh 9 sptr,int #comfunc global IDirect3DCryptoSession9_FinishSessionKeyRefresh 10 #comfunc global IDirect3DCryptoSession9_GetEncryptionBltKey 11 sptr,int ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。#define global IID_IDirect3DCryptoSession9 "{FA0AB799-7A9C-48CA-8C5B-237E71A54434}" #usecom global IDirect3DCryptoSession9 IID_IDirect3DCryptoSession9 "{}" #comfunc global IDirect3DCryptoSession9_GetCertificateSize 3 sptr #comfunc global IDirect3DCryptoSession9_GetCertificate 4 int,sptr #comfunc global IDirect3DCryptoSession9_NegotiateKeyExchange 5 int,sptr #comfunc global IDirect3DCryptoSession9_EncryptionBlt 6 sptr,sptr,int,sptr #comfunc global IDirect3DCryptoSession9_DecryptionBlt 7 sptr,sptr,int,sptr,sptr,sptr #comfunc global IDirect3DCryptoSession9_GetSurfacePitch 8 sptr,sptr #comfunc global IDirect3DCryptoSession9_StartSessionKeyRefresh 9 sptr,int #comfunc global IDirect3DCryptoSession9_FinishSessionKeyRefresh 10 #comfunc global IDirect3DCryptoSession9_GetEncryptionBltKey 11 sptr,int ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。