C
输出验证
输出验证的目的是确保安全项目的显示内容完整性。完整性检查基于离线计算和图形输出之间的 CRC(循环冗余检查)值的比较。
Qt 安全渲染器提供一个机制来生成预期的 CRC 并从硬件中读取实际的输出 CRC 值。检测到失败时的动作不在 Qt 安全渲染器的范围之内,而是系统逻辑的一部分。
从 Qt 安全渲染器 2.0 版本开始支持输出验证。
使用 fillColor 属性
在 UI 中,几个图形缓冲区在显示处理器中混合成最终的显示内容。输出 CRC 值从这些数据计算得出。因此,安全项目的背景色不能是透明的。相反,您应该使用纯色背景色。
使用 fillColor
属性定义安全项目的背景色
此外,在为隐藏的安全项目进行输出验证时,也使用纯色背景色。当安全项目被隐藏时,其在 UI 中的图标区域使用在 fillColor
属性中定义的纯色进行清除。隐藏安全项目的输出验证将验证清除是否按预期工作。
注意:如果背景填充颜色几乎是纯色,它可以使安全关键元素通过对比度检查。仍有可能由于非安全背景可以通过部分透明的元素看到,这会影响 CRC 计算,导致 CRC 输出验证失败。
使用 OutputVerifier 类
通过创建 SafeRenderer::OutputVerifier 类的实例来启用输出验证器。引用按如下方式传递给 SafeRenderer::SafeWindow 和 SafeRenderer::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示例的渲染输出。
限制条件
不支持验证动态文本输出。
支持的硬件
以下参考硬件配置支持此功能
- Qualcomm Snapdragon SA8155P与QNX 7.0和QNX OS for Safety 2.0
- Qualcomm Snapdragon SA6155P与QNX 7.0和QNX OS for Safety 2.0
输出验证API
以下类和事件提供了输出验证和监控的API
在特定的Qt许可下可用。
了解更多信息。