C

输出验证

输出验证的目的是确保安全项目的显示内容完整性。完整性检查基于离线计算和图形输出之间的 CRC(循环冗余检查)值的比较。

Qt 安全渲染器提供一个机制来生成预期的 CRC 并从硬件中读取实际的输出 CRC 值。检测到失败时的动作不在 Qt 安全渲染器的范围之内,而是系统逻辑的一部分。

从 Qt 安全渲染器 2.0 版本开始支持输出验证。

使用 fillColor 属性

在 UI 中,几个图形缓冲区在显示处理器中混合成最终的显示内容。输出 CRC 值从这些数据计算得出。因此,安全项目的背景色不能是透明的。相反,您应该使用纯色背景色。

使用 fillColor 属性定义安全项目的背景色

此外,在为隐藏的安全项目进行输出验证时,也使用纯色背景色。当安全项目被隐藏时,其在 UI 中的图标区域使用在 fillColor 属性中定义的纯色进行清除。隐藏安全项目的输出验证将验证清除是否按预期工作。

注意:如果背景填充颜色几乎是纯色,它可以使安全关键元素通过对比度检查。仍有可能由于非安全背景可以通过部分透明的元素看到,这会影响 CRC 计算,导致 CRC 输出验证失败。

使用 OutputVerifier 类

通过创建 SafeRenderer::OutputVerifier 类的实例来启用输出验证器。引用按如下方式传递给 SafeRenderer::SafeWindowSafeRenderer::EventHandler

static OutputVerifier outputVerifier;
static QSafeLayoutResourceReader layout("/layoutData/MainForm/MainForm.ui.srl");
SafeWindow telltaleWindow(layout.size(), QSafePoint(0U, 0U), outputVerifier);
static SafeRenderer::StateManager stateManager(telltaleWindow, layout, background);
EventHandler msgHandler(stateManager, telltaleWindow, outputVerifier);

SafeWindow 实现读取已更改项渲染后的输出 CRC 值。结果值存储在 SafeRenderer::OutputVerificationQueue 中。

可以使用 SafeRenderer::QSafeEventOutputVerificationStatusRequest 事件从安全渲染器进程中读取结果。输出 CRC 值将被打包到 SafeRenderer::QSafeEventOutputVerificationStatusReply 事件中。

Golden CRC 值

Qt 安全布局工具计算可见和隐藏状态下每个 QML 项目的 Golden CRC 值。这些值存储在布局文件中,并可以使用 SafeRenderer::QSafeLayout 类读取。

libcalccrc 库

使用 libcalccrc 库来计算 Golden CRC。该算法是硬件特定的,Qt 安全渲染器 2.0 为高通骁龙硬件提供了实现。

如果 libcalccrc 库在 <QSR 安装目录>/Src/QtSafeRenderer-<版本>/lib 或 Qt 安装文件夹下找不到,则使用库的存根版本。您应该仅与非骁龙硬件一起使用。

Golden CRC 示例

以下代码片段可以在外部进程中用来读取金标签CRC值进行比较。

struct ExpectedCRCValues {
    quint32 drawCRC;
    quint32 clearCRC;
};

bool getExpectedCRC(const char*const filenameArg, const quint32 idArg, ExpectedCRCValues &crcValues)
{
    bool found = false;
    crcValues = {0U, 0U};
    //Initialize the resource
    const QSafeResource res;
    size_t sizeOfData = 0U;
    //Get the resource structure for the layout file
    const quchar *const data = res.data(filenameArg, sizeOfData);
    const QSafeByteArray layoutData(data, sizeOfData);
    //Validate the layout data file
    const quint32 itemCount = QSafeLayout::validateLayout(layoutData);
    size_t offsetInWords = Constraints::LAYOUTDATA_HEADER_SIZE;
    const quint32 layoutDataSize = QSafeLayout::layoutDataSize(QSafeLayout::layoutVersion(layoutData));
    if (data) {
        //Go through the layoutdata file
        for (quint32 i=0U; i<itemCount; i++) {
            const quint32 itemIDOffset = offsetInWords + QSafeLayout::ItemIDOffset;
            const quint32 id = layoutData.readUInt32ValueConst(itemIDOffset);
            //If item is found get the CRC values.
            if (id == idArg) {
                const quint32 drawCRCOffset = offsetInWords + QSafeLayout::OutputCRCDrawOffset;
                const quint32 clearCRCOffset = offsetInWords + QSafeLayout::OutputCRCClearOffset;
                crcValues.drawCRC = layoutData.readUInt32ValueConst(drawCRCOffset);
                crcValues.clearCRC = layoutData.readUInt32ValueConst(clearCRCOffset);
                found = true;
                break;
            }
            offsetInWords += layoutDataSize;
        }
    }
    return found;
}

更新输出CRC值

在每次渲染脏区域操作之后读取输出CRC值。还可以手动读取单个元素的CRC值。可以使用SafeRenderer::QSafeEventOutputVerificationVerifyItem事件来更新单个项目的CRC值。

读取输出CRC值

输出CRC值存储在SafeRenderer::OutputVerificationQueue类中。可以使用SafeRenderer::QSafeEventOutputVerificationStatusRequest事件从队列中读取值。《SafeRenderer::QSafeEventOutputVerificationStatusReply事件包含ID和CRC值对的列表。

监控输出验证

您可以从外部进程监控输出验证的结果。《Monitor示例演示了您如何从外部的Monitor进程验证《Indicators示例的渲染输出。

限制条件

不支持验证动态文本输出。

支持的硬件

以下参考硬件配置支持此功能

输出验证API

以下类和事件提供了输出验证和监控的API

在特定的Qt许可下可用。
了解更多信息。