window显示驱动开发—可选内容保护 DDI 函数

驱动程序可以选择性地支持以下内容保护 DDI 函数:

  • EncryptionBlt 函数从受保护的图面读取加密数据。
  • GetPitch 函数检索受保护图面的间距。
  • StartSessionKeyRefresh 函数返回一个随机数,解码器/应用程序和驱动程序/硬件随后可以使用该随机数执行独占 OR 操作, (XOR) 会话密钥。
  • FinishSessionKeyRefresh 函数指示来自该时间点的所有缓冲区都将使用更新的会话键值。
  • GetEncryptionBltKey 函数返回用于解密驱动程序的 EncryptionBlt 函数返回的数据的密钥。
  • DecryptionBlt 函数将数据写入受保护的图面。

1. EncryptionBlt - 受保护图面数据读取

1.1 函数原型

复制代码
HRESULT APIENTRY EncryptionBlt(
    D3DDDIARG_ENCRYPTIONBLT* pEncryptBlt);

1.2 实现要点

复制代码
HRESULT APIENTRY EncryptionBlt(D3DDDIARG_ENCRYPTIONBLT* pEncryptBlt)
{
    // 验证输入参数
    if (!pEncryptBlt->hSrcResource || !pEncryptBlt->pEncryptedBlock)
        return E_INVALIDARG;

    // 检查资源保护状态
    if (!IsResourceProtected(pEncryptBlt->hSrcResource))
        return D3DDDIERR_INVALIDPROTECT;

    // 获取加密密钥句柄
    HCRYPTKEY hKey = GetCurrentSessionKey();

    // 使用硬件加密引擎
    if (FAILED(HW_EncryptSurface(
            pEncryptBlt->hSrcResource,
            pEncryptBlt->pEncryptedBlock,
            pEncryptBlt->EncryptedBlockSize,
            hKey))) {
        return E_FAIL;
    }

    return S_OK;
}

安全要求:

必须验证源资源具有D3DUSAGE_PROTECTED标志

加密操作应在安全执行环境(TEE)中完成

输出数据必须使用会话密钥加密

2. GetPitch - 获取受保护图面间距

2.1 典型实现

复制代码
HRESULT APIENTRY GetPitch(
    D3DDDIARG_GETPITCH* pGetPitch)
{
    RESOURCE_CTX* pResCtx = (RESOURCE_CTX*)pGetPitch->hResource;
    
    // 保护资源需要特殊对齐
    if (pResCtx->Flags.Protected) {
        pGetPitch->Pitch = ALIGN_UP(pResCtx->Width, 64);
    } else {
        pGetPitch->Pitch = pResCtx->Pitch;
    }
    
    return S_OK;
}

注意事项:

  • 保护图面通常需要64字节或128字节对齐
  • 间距值应匹配硬件加密引擎要求

3. 会话密钥刷新机制

3.1 StartSessionKeyRefresh

复制代码
HRESULT APIENTRY StartSessionKeyRefresh(
    D3DDDIARG_STARTSESSIONKEYREFRESH* pKeyRefresh)
{
    CRYPTO_SESSION_CTX* pSession = 
        (CRYPTO_SESSION_CTX*)pKeyRefresh->hCryptoSession;
    
    // 生成安全随机数
    BCryptGenRandom(
        NULL,
        pKeyRefresh->pRandomNumber,
        pKeyRefresh->RandomNumberSize,
        BCRYPT_USE_SYSTEM_PREFERRED_RNG);
    
    // 保存原始密钥用于过渡期
    pSession->PendingKeyRefresh = TRUE;
    memcpy(pSession->OldKey, pSession->CurrentKey, KEY_SIZE);
    
    return S_OK;
}

3.2 FinishSessionKeyRefresh

复制代码
HRESULT APIENTRY FinishSessionKeyRefresh(
    D3DDDIARG_FINISHSESSIONKEYREFRESH* pKeyRefresh)
{
    CRYPTO_SESSION_CTX* pSession = 
        (CRYPTO_SESSION_CTX*)pKeyRefresh->hCryptoSession;
    
    if (!pSession->PendingKeyRefresh)
        return D3DDDIERR_INVALIDCALL;
    
    // 应用新密钥
    XOR_Keys(pSession->CurrentKey, pKeyRefresh->pXORKey);
    
    // 清除过渡状态
    pSession->PendingKeyRefresh = FALSE;
    SecureZeroMemory(pSession->OldKey, KEY_SIZE);
    
    return S_OK;
}

密钥刷新流程:

4. GetEncryptionBltKey - 获取解密密钥

4.1 安全实现

复制代码
HRESULT APIENTRY GetEncryptionBltKey(
    D3DDDIARG_GETENCRYPTIONBLTKEY* pKeyData)
{
    if (!pKeyData->hCryptoSession)
        return E_INVALIDARG;
    
    CRYPTO_SESSION_CTX* pSession = 
        (CRYPTO_SESSION_CTX*)pKeyData->hCryptoSession;
    
    // 密钥必须加密传输
    if (FAILED(EncryptKeyForTransport(
            pSession->CurrentKey,
            pKeyData->pKey,
            pKeyData->KeySize))) {
        return E_FAIL;
    }
    
    return S_OK;
}

保护措施:

  • 使用接收方公钥加密传输密钥
  • 限制密钥有效时间(通常<2秒)

5. DecryptionBlt - 受保护图面写入

5.1 完整实现

复制代码
HRESULT APIENTRY DecryptionBlt(
    D3DDDIARG_DECRYPTIONBLT* pDecryptBlt)
{
    // 参数验证
    if (!pDecryptBlt->hDstResource || !pDecryptBlt->pEncryptedBlock)
        return E_INVALIDARG;
    
    // 检查目标保护状态
    if (!IsResourceProtected(pDecryptBlt->hDstResource))
        return D3DDDIERR_INVALIDPROTECT;
    
    // 获取当前会话密钥
    HCRYPTKEY hKey = GetCurrentSessionKey();
    
    // 硬件解密操作
    if (FAILED(HW_DecryptToSurface(
            pDecryptBlt->pEncryptedBlock,
            pDecryptBlt->EncryptedBlockSize,
            pDecryptBlt->hDstResource,
            hKey))) {
        return E_FAIL;
    }
    
    return S_OK;
}

6. 安全架构设计

6.1 密钥生命周期管理

复制代码
stateDiagram-v2
    [*] --> KeyGen: CreateCryptoSession
    KeyGen --> Active: 正常使用
    Active --> Refreshing: StartRefresh
    Refreshing --> Active: FinishRefresh
    Active --> Revoked: 检测到攻击
    Revoked --> [*]

6.2 内存保护机制

复制代码
typedef struct _PROTECTED_RESOURCE {
    D3DKMT_HANDLE hAllocation;
    BOOL IsEncrypted;
    PHYSICAL_ADDRESS SecurePA; // 受保护物理地址
    CRYPTO_KEY_HANDLE hKey;    // 关联密钥
} PROTECTED_RESOURCE;

7. 性能优化技巧

批量加密操作:

复制代码
void OptimizedEncryptionBlt()
{
    if (SupportsBulkEncrypt()) {
        HW_BulkEncrypt(/* 多个表面 */);
    } else {
        // 回退到单表面处理
    }
}

密钥缓存:

复制代码
class KeyCache {
public:
    void CacheKey(HCRYPTOKEY hKey, const BYTE* pKeyData) {
        m_cache[hKey] = SecureDuplicateKey(pKeyData);
    }
private:
    std::map<HCRYPTOKEY, SecureKey> m_cache;
};

8. 认证测试要求

WHQL测试项目:

  • 强制密钥刷新测试
  • 加密/解密往返验证
  • 无效句柄测试

抗攻击测试:

复制代码
# 伪代码:模拟中间人攻击
def test_key_refresh_attack():
    orig_key = get_key()
    start_refresh()
    inject_fake_key()
    assert system_rejects_finish()

9. 错误处理规范

错误码 描述
D3DDDIERR_INVALIDPROTECT 资源保护状态不匹配
D3DDDIERR_KEYEDTOOMANY 密钥使用次数超限
E_CRYPTO_NOT_INIT 加密引擎未初始化
相关推荐
万物智能信息科技17 小时前
六轴传感器Motion驱动框架开发—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】
驱动开发·华为·开源·harmonyos·鸿蒙
AMASENSYS艾马斯2 天前
变频器滤波器选型与EMC合规建议
驱动开发·单片机·其他·硬件工程·精益工程
沃普天科技2 天前
100W 氮化镓充电器充电头扩展坞一体化设计,实用性翻倍
驱动开发·计算机外设·音视频·硬件工程·pcb工艺
lisw053 天前
算法与软件的本质区别
驱动开发·算法·数学建模
泡海椒3 天前
JQuick-SQL “数据源 SPI”辨析:应用适配器与 Function SPI 的正确边界
数据库·驱动开发·sql
万物智能信息科技3 天前
Zigbee透传驱动开发—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】
驱动开发·华为·开源·harmonyos·鸿蒙
AMASENSYS艾马斯3 天前
低压变频器输入输出电抗器选型指南
驱动开发·单片机·机器学习·硬件工程·精益工程
软件工程师文艺4 天前
AI 编程新范式:Spec Kit 的规格驱动开发到底在解决什么
人工智能·驱动开发
AMASENSYS艾马斯5 天前
变频器过载能力参数解读与工程应用
驱动开发·嵌入式硬件·其他·硬件工程·精益工程
万物智能信息科技5 天前
LoRa串口透传驱动开发—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】
驱动开发·嵌入式硬件·华为·开源·harmonyos