

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 移植 AWS IoT over-the-air (OTA) 更新库
<a name="afr-porting-ota"></a>

通过 FreeRT over-the-air OS (OTA) 更新，您可以执行以下操作：
+ 将固件映像部署到单个设备、一组设备或整个机群。
+ 在将设备添加到组，或重置或重新预配置设备时，将固件部署到设备。
+ 将新固件部署到设备之后，验证其真实性和完整性。
+ 监控部署进度。
+ 调试失败的部署。
+ 使用代码签名对固件进行数字签名。 AWS IoT

[有关更多信息，请参阅 [FreeRTOS Over-the-Air 用户](https://docs.aws.amazon.com/freertos/latest/userguide/freertos-ota-dev.html)指南中的 *FreeRTOS 更新以及更新*文档。AWS IoT Over-the-air ](https://freertos.org/Documentation/api-ref/ota-for-aws-iot-embedded-sdk/docs/doxygen/output/html/index.html)

您可以使用 OTA 更新库将 OTA 功能集成到您的 FreeRTOS 应用程序中。有关更多信息，请参阅《FreeRTOS 用户指南》中的 [FreeRTOS OTA 更新库](https://docs.aws.amazon.com/freertos/latest/userguide/ota-update-library.html)。**

FreeRTOS 设备必须在它们接收到的 OTA 固件映像上强制实施加密代码签名验证。我们建议采用下列算法：
+ 椭圆曲线数字签名算法 (ECDSA)
+ NIST P256 曲线
+ SHA-256 哈希

## 先决条件
<a name="porting-prereqs-ota"></a>
+ 完成[为移植设置工作区和项目](porting-set-up-project.md)中的说明。
+ 创建网络传输接口端口。

  有关信息，请参阅[移植网络传输接口](afr-porting-network-transport-interface.md)。
+ 集成 coreMQTT 库。请参阅《FreeRTOS 用户指南》中的 [coreMQTT 库](https://docs.aws.amazon.com/freertos/latest/userguide/coremqtt.html)。
+ 创建 OTA 更新的引导加载程序。

## 平台移植
<a name="porting-steps-ota"></a>

您必须提供 OTA 便携式抽象层 (PAL) 的实现才能将 OTA 库移植到新设备。PAL APIs 是在 [ota\$1platform\$1interface.h](https://github.com/aws/ota-for-aws-iot-embedded-sdk/blob/main/source/include/ota_platform_interface.h) 文件中定义的，必须提供具体的实现细节。


| 函数名称 | 说明 | 
| --- | --- | 
| `otaPal_Abort` | 停止 OTA 更新。 | 
| `otaPal_CreateFileForRx` | 创建一个文件来存储收到的数据块。 | 
| `otaPal_CloseFile` | 关闭指定的文件。如果使用实现加密保护的存储，则可能会对文件进行身份验证。 | 
| `otaPal_WriteBlock` | 按照指定偏移量将数据块写入指定文件。如果成功，则返回写入的字节数。否则，该函数返回负错误代码。数据块大小始终为二的乘方，并且将保持对齐。有关更多信息，请参阅 [OTA 库配置](https://freertos.org/Documentation/api-ref/ota-for-aws-iot-embedded-sdk/docs/doxygen/output/html/ota_config.html)。 | 
| `otaPal_ActivateNewImage` | 激活或启动新的固件映像。对于某些端口，如果以编程方式同步重置设备，此函数将不会返回。 | 
| `otaPal_SetPlatformImageState` | 执行平台所需的任何操作来接受或拒绝最新的 OTA 固件映像（或包）。要实现此函数，请参阅您的主板（平台）的文档以了解详细信息和架构。 | 
| `otaPal_GetPlatformImageState` | 获取 OTA 更新映像的状态。 | 

如果您的设备已内置相应支持，实施此表中的函数。


| 函数名称 | 说明 | 
| --- | --- | 
| `otaPal_CheckFileSignature` | 验证指定文件的签名。 | 
| `otaPal_ReadAndAssumeCertificate` | 从文件系统读取指定的签署人证书并将其返回给调用方。 | 
| `otaPal_ResetDevice` | 重置设备。 | 

**注意**  
确保您有支持 OTA 更新的引导加载程序。有关创建 AWS IoT 设备引导加载程序的说明，请参阅[IoT 设备引导加载程序](#afr-bootloader)。

## E2E 和 PAL 测试
<a name="porting-steps-testing"></a>

 运行 OTA PAL 和 E2E 测试。

### E2E 测试
<a name="porting-ota-e2e"></a>

OTA 端到端 (E2E) 测试用于验证设备的 OTA 能力和模拟现实场景。该测试包括错误处理。

#### 先决条件
<a name="e2e-prereqs"></a>

要完成此测试，您需要具备以下条件：
+ 一个集成了 AWS OTA 库的项目。有关更多信息，请访问[《OTA 库移植指南》](https://www.freertos.org/Documentation/api-ref/ota-for-aws-iot-embedded-sdk/docs/doxygen/output/html/ota_porting.html)。
+ 使用 OTA 库移植演示应用程序与 AWS IoT Core 交互以进行 OTA 更新。请参阅[移植 OTA 演示应用程序](#e2e-porting-demo-application)。
+ 设置 IDT 工具。这将运行 OTA E2E 主机应用程序来构建、刷写和监控具有不同配置的设备，并验证 OTA 库的集成。

#### 移植 OTA 演示应用程序
<a name="e2e-porting-demo-application"></a>

OTA E2E 测试必须有 OTA 演示应用程序才能验证 OTA 库的集成。该演示应用程序必须具有执行 OTA 固件更新的能力。[你可以在 FreeRTOS 存储库中找到 FreeRTOS OTA 演示应用程序。 GitHub](https://github.com/FreeRTOS/FreeRTOS/tree/main/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator)我们建议您使用该演示应用程序作为参考，并根据您的规范进行修改。

##### 移植测试
<a name="e2e-port-demo"></a>

1. 初始化 OTA 代理。

1. 实现 OTA 应用程序回调函数。

1. 创建 OTA 代理事件处理任务。

1. 启动 OTA 代理。

1. 监控 OTA 代理统计信息。

1. 关闭 OTA 代理。

有关详细说明，请访问 [FreeRTOS OTA over MQTT - 演示的入口点](https://www.freertos.org/ota/ota-mqtt-agent-demo.html#OtaMqttAgentEntryPoint)。

##### 配置
<a name="e2e-port-config"></a>

必须使用以下配置才能与之交互 AWS IoT Core：
+ AWS IoT Core 客户凭证
  + 在 `Ota_Over_Mqtt_Demo/demo_config.h` 中使用 Amazon Trust Services 端点设置 **democonfigROOT\$1CA\$1PEM**。有关更多详细信息，请参阅 [AWS 服务器身份验证](https://docs.aws.amazon.com/iot/latest/developerguide/server-authentication.html)。
  + **使用你的客户端**凭据设置 democonfigClient\$1certificate\$1pem 和 democonfigClient\$1Private\$1key\$1pem**。** `Ota_Over_Mqtt_Demo/demo_config.h` AWS IoT 要了解有关客户端证书和私有密钥的信息，请参阅 [AWS 客户端身份验证详细信息](https://docs.aws.amazon.com/iot/latest/developerguide/client-authentication.html)。
+ 应用程序版本
+ OTA 控制协议
+ OTA 数据协议
+ 代码签名凭证
+ 其他 OTA 库配置

在 FreeRTOS OTA 演示应用程序中，您可以在 `demo_config.h` 和 `ota_config.h` 中找到上述信息。有关更多信息，请访问 [FreeRTOS OTA over MQTT - 设置设备](https://www.freertos.org/ota/ota-mqtt-agent-demo.html#OTABasicDemoClient)。

##### 构建验证
<a name="e2e-port-validation"></a>

运行演示应用程序以运行 OTA 作业。成功完成后，您可以继续运行 OTA E2E 测试。

F [reeRTOS OTA](https://www.freertos.org/ota/ota-mqtt-agent-demo.html) 演示提供了有关在 FreeRTOS Windows 模拟器上设置 OTA 客户端和 AWS IoT Core OTA 作业的详细信息。 AWS OTA 同时支持 MQTT 和 HTTP 协议。有关更多详细信息，请参阅以下示例：
+ [Windows 模拟器上的 OTA over MQTT 演示](https://github.com/FreeRTOS/FreeRTOS/tree/main/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo)
+ [Windows 模拟器上的 OTA over HTTP 演示](https://github.com/FreeRTOS/FreeRTOS/tree/main/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo)

#### 使用 IDT 工具运行测试
<a name="e2e-idt"></a>

要运行 OTA 端到端测试，必须使用 AWS IoT Device Tester (IDT) 自动执行。有关更多详细信息，请参阅《FreeRTOS 用户指南》中 [适用于 FreeRTOS 的AWS IoT Device Tester](https://docs.aws.amazon.com/freertos/latest/userguide/device-tester-for-freertos-ug.html)。**

##### E2E 测试用例
<a name="e2e-test-cases"></a>


| 测试用例 | 说明 | 
| --- | --- | 
| `OTAE2EGreaterVersion` | 定期 OTA 更新的满意路径 (Happy Path) 测试。它使用设备成功更新的新版本创建更新。 | 
| `OTAE2EBackToBackDownloads` | 此测试会连续创建 3 个 OTA 更新。预计设备将连续更新 3 次。 | 
| `OTAE2ERollbackIfUnableToConnectAfterUpdate` | 此测试会验证当设备无法使用新固件连接到网络时，是否会回滚到以前的固件。 | 
| `OTAE2ESameVersion` | 此测试确认，如果传入的固件版本保持不变，则设备会拒绝接收该固件。 | 
| `OTAE2EUnsignedImage` | 此测试验证当镜像没有签名时，设备是否会拒绝更新。 | 
| `OTAE2EUntrustedCertificate` | 如果固件使用不受信任的证书签名，此测试将验证设备是否会拒绝更新。 | 
| `OTAE2EPreviousVersion` | 此测试验证设备是否拒绝了旧更新版本。 | 
| `OTAE2EIncorrectSigningAlgorithm` | 不同的设备支持不同的签名和哈希算法。如果设备使用不支持的算法创建，则此测试会验证 OTA 更新是否失败。 | 
| `OTAE2EDisconnectResume` | 这是暂停和恢复功能的成功路径测试。此测试创建 OTA 更新并开始更新。然后，它 AWS IoT Core 使用相同的客户端 ID（事物名称）和凭据进行连接。 AWS IoT Core 然后断开设备的连接。设备应检测到已与其断开连接 AWS IoT Core，一段时间后，设备会自行进入暂停状态，然后尝试重新连接 AWS IoT Core 并恢复下载。 | 
| `OTAE2EDisconnectCancelUpdate` | 当设备处于暂停状态时，如果取消 OTA 任务，此测试会检查设备能否自行恢复。它的作用与`OTAE2EDisconnectResume`测试相同，只是在连接到设备后 AWS IoT Core，它会断开设备连接，从而取消OTA更新。新更新已创建。设备应重新连接到 AWS IoT Core，中止当前更新，返回等待状态，接受并完成下一次更新。 | 
| `OTAE2EPresignedUrlExpired` | 创建 OTA 更新时，您可以配置 S3 预签名 URL 的生命周期。此测试会验证设备是否能够执行 OTA，即使它无法在 URL 过期时完成下载。此设备应请求新的任务文档，其中包含用于恢复下载的新 URL。 | 
| `OTAE2E2UpdatesCancel1st` | 此测试会连续创建两个 OTA 更新。当设备报告正在下载第一个更新时，测试人员会强制取消第一个更新。设备预计会中止当前更新并进行第二次更新，然后完成更新。 | 
| `OTAE2ECancelThenUpdate` | 此测试会连续创建两个 OTA 更新。当设备报告正在下载第一个更新时，测试人员会强制取消第一个更新。设备预计会中止当前更新并进行第二次更新，然后完成更新。 | 
| `OTAE2EImageCrashed` | 此测试会检查设备是否能够在映像崩溃时拒绝更新。 | 

### PAL 测试
<a name="porting-ota-pal"></a>

#### 先决条件
<a name="pal-prereqs"></a>

要移植网络传输接口测试，您需要具备以下几点：
+ 一个可使用有效的 FreeRTOS 内核端口构建 FreeRTOS 的项目。
+ OTA PAL 的有效实现。

#### 移植
<a name="pal-porting"></a>
+ 将 [FreeRTOS-Libraries-Integration-Tests](https://github.com/FreeRTOS/FreeRTOS-Libraries-Integration-Tests) 作为子模块添加到您的项目中。子模块必须位于项目中可构建该子模块的位置。
+ 将 `config_template/test_execution_config_template.h` 和 `config_template/test_param_config_template.h` 复制到构建路径中的位置，然后将其重命名为 `test_execution_config.h` 和 `test_param_config.h`。
+ 将相关文件包含到构建系统中。如果使用 `CMake`，则可以使用 `qualification_test.cmake` 和 `src/ota_pal_tests.cmake` 来包含相关文件。
+ 通过实现以下功能来配置测试：
  + `SetupOtaPalTestParam()`：在 `src/ota/ota_pal_test.h` 中定义。实现的名称和签名必须与 `ota_pal_test.h` 中定义的完全相同。目前，您不需要配置此函数。
+ 实现 **UNITY\$1OUTPUT\$1CHAR**，这样，测试输出日志就不会与设备日志交错。
+ 从应用程序调用 `RunQualificationTest()`。在调用之前，必须正确初始化设备硬件并连接网络。

#### 测试
<a name="ota-testing"></a>

本节介绍 OTA PAL 资格认证测试的本地测试。

##### 启用测试
<a name="ota-testing-enabling"></a>

打开 `test_execution_config.h` 并将 **OTA\$1PAL\$1TEST\$1ENABLED** 定义为 1。

在 `test_param_config.h` 中，更新以下选项：
+ **OTA\$1PAL\$1TEST\$1CERT\$1TYPE**：选择使用的证书类型。
+ **OTA\$1PAL\$1CERTIFICATE\$1FILE**：设备证书的路径（如果适用）。
+ **OTA\$1PAL\$1FIRMWARE\$1FILE**：固件文件的名称（如果适用）。
+ **OTA\$1PAL\$1USE\$1FILE\$1SYSTEM**：如果 OTA PAL 使用文件系统抽象，则设置为 1。

使用您选择的工具链构建和刷写应用程序。调用 `RunQualificationTest()` 时，OTA PAL 测试将运行。测试结果会输出到串行端口。

### 集成 OTA 任务
<a name="integrating-ota"></a>
+ 在您当前的 MQTT 演示中添加 OTA 代理。
+ 使用运行 OTA 端到端 (E2E) 测试。 AWS IoT这会验证集成是否按预期运行。

**注意**  
要使设备正式获得FreeRTOS的资格，您必须使用OTA PAL和OTA E2E测试组验证设备的移植源代码。 AWS IoT Device Tester按照《[FreeRTOS 用户指南》中的 “用 AWS IoT Device Tester 于](https://docs.aws.amazon.com/freertos/latest/userguide/device-tester-for-freertos-ug.html) *FreeRTOS” 中的说明进行端口验证*设置。 AWS IoT Device Tester 要测试特定库的端口，必须在 AWS IoT Device Tester `configs`文件夹`device.json`的文件中启用正确的测试组。

## IoT 设备引导加载程序
<a name="afr-bootloader"></a>

您必须提供自己的安全引导加载程序应用程序。确保设计和实施能够适当缓解安全威胁。以下是供您参考的威胁建模。

### IoT 设备引导加载程序的威胁建模
<a name="afr-threat-model-for-bootloader"></a>

#### 背景
<a name="afr-threat-model-for-bootloader-background"></a>

作为一个可行的定义，此威胁模型所指的嵌入式 AWS IoT 设备是基于微控制器的与云服务交互的产品。它们可以部署在消费者、商业或工业环境中。IoT 设备可以收集有关用户、患者、机器或环境的数据，并且可以控制从灯泡和门锁到工厂机器的任何事物。

从假设对手的角度看，威胁建模是一种保护安全的方法。通过考虑对手的目标和方法，创建了一个威胁列表。威胁是对手对资源或资产发起的攻击。该列表具有优先级，并用于确定或创建缓解解决方案。在选择缓解解决方案时，实施和维护这些解决方案的成本应与它提供的实际安全价值平衡。可以使用多种[威胁模型方法](https://en.wikipedia.org/wiki/Threat_model)。每种产品都能够支持安全且成功的 AWS IoT 产品的开发。

FreeRTOS 为设备提供 OTA over-the-air () 软件更新。 AWS IoT 更新工具将云服务与设备上的软件库和合作伙伴提供的引导加载程序结合使用。该威胁模型明确侧重于针对引导加载程序的威胁。

**引导加载程序使用案例**
+ 在部署之前对固件进行数字签名和加密。
+ 将新的固件映像部署到单个设备、一组设备或整个队列中。
+ 在新固件部署到设备之后，验证其真实性和完整性。
+ 设备仅运行来自受信任的来源的未修改软件。
+ 设备可以灵活处理通过 OTA 收到的故障软件。

**数据流程图**

![\[针对嵌入式设备安全的数据流程图（包含物理访问、嵌入式设备、互联网边界和其他组件）。\]](http://docs.aws.amazon.com/zh_cn/freertos/latest/portingguide/images/bootloader-dataflow-diagram.png)


#### 威胁
<a name="afr-threat-model-for-bootloader-threats"></a>

有些攻击有多种缓解模式；例如，通过验证对 TLS 服务器提供的证书和新固件映像的代码签名者证书的信任度，可以缓解 man-in-the-middle旨在提供恶意固件映像的网络。为了最大限度提高引导加载程序的安全性，任何非引导加载程序缓解解决方案都被视为不可靠。引导加载程序应具有每种攻击的内置缓解解决方案。采用分层缓解解决方案被称为 defense-in-depth。

**威胁：**
+ 攻击者劫持设备到服务器的连接以提供恶意固件映像。

**缓解措施示例**
  + 在引导时，引导加载程序使用已知证书验证映像的加密签名。如果验证失败，引导加载程序将回滚到上一个映像。
+ 攻击者利用缓冲区溢出以将恶意行为引入到闪存中存储的现有固件映像。

**缓解措施示例**
  + 在引导时，引导加载程序将按照上面所述进行验证。如果验证失败并且没有以前的映像，引导加载程序将停止。
  + 在引导时，引导加载程序将按照上面所述进行验证。如果验证失败且没有以前的映像，引导加载程序将进入仅 OTA 故障保护模式。
+ 攻击者将设备引导到以前存储的映像，从而可以利用该映像发起攻击。

**缓解措施示例**
  + 在成功安装和测试新映像后，将擦除存储上一个映像的闪存扇区。
  + 在每次成功升级时，都会熔断保险丝，每个映像将会重新熔断保险丝才能运行，除非已熔断正确数量的保险丝。
+ OTA 更新提供故障或恶意映像，从而导致设备无法正常运行。

**缓解措施示例**
  + 引导加载程序启动硬件监视程序计时器，以触发回滚到上一个映像。
+ 攻击者修补引导加载程序以绕过映像验证，因此，设备将接受未签名的映像。

**缓解措施示例**
  + 引导加载程序位于 ROM（只读存储器）中，无法进行修改。
  + 引导加载程序位于 OTP（one-time-programmable 内存）中，无法修改。
  + 引导加载程序位于 ARM 的安全区域中 TrustZone，无法修改。
+ 攻击者替换验证证书，因此，设备将接受恶意映像。

**缓解措施示例**
  + 证书位于加密协处理器中，无法进行修改。
  + 证书位于 ROM、OTP 或安全区域中，无法进行修改。

#### 进一步的威胁建模
<a name="afr-threat-model-for-bootloader-further"></a>

该威胁模型仅考虑引导加载程序。进一步的威胁建模可能会提高整体安全性。建议的方法是列出对手的目标、这些目标针对的资产以及资产的入口点。可以考虑为控制资产而对入口点发起的攻击以创建威胁列表。以下是 IoT 设备的目标、资产和入口点示例列表。这些列表并非详尽无遗，旨在为您提供一些启发。

**对手的目标**
+ 敲诈钱财 
+ 诋毁声誉 
+ 伪造数据 
+ 转移资源 
+ 远程监视目标 
+ 实际访问站点 
+ 造成严重破坏
+ 灌输恐怖 

**主要资产**
+ 私有密钥 
+ 客户端证书 
+ CA 根证书 
+ 安全凭证和令牌 
+ 客户的个人身份信息 
+ 商业机密实施 
+ 传感器数据 
+ 云分析数据存储 
+ 云基础设施 

**入口点**
+ DHCP 响应 
+ DNS 响应 
+ 基于 TLS 的 MQTT 
+ HTTPS 响应 
+ OTA 软件映像 
+ 应用程序指示的其他内容，例如 USB 
+ 实际访问总线 
+ 开封 IC 