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许可下可用。
了解更多信息。