1438 lines
67 KiB
Markdown
1438 lines
67 KiB
Markdown
# 加密驱动规范 (Specification of Crypto Driver)
|
||
|
||
**AUTOSAR CP Release 4.4.0**
|
||
|
||
> 翻译说明:本文档为 AUTOSAR 经典平台 (CP) Release 4.4.0 中 SWS 文档 807《Specification of Crypto Driver》的中文翻译版本。原始英文文档中的 AUTOSAR 方框符 `⌈⌋`、API 标识符(如 `Crypto_ProcessJob`)、模块缩写(Crypto、CryIf、Csm、KeyM 等)、加密算法名(AES、SHA、RSA、ECC 等)以及需求 ID(如 `SWS_Crypto_xxxxx`)均予以保留。本文采用"重点翻译 + 摘要"策略:完整翻译封面、标识、变更历史、目录、关键 API 及核心概念;重复函数的需求条目予以摘要处理。完整定义参见原始 PDF。
|
||
|
||
## 文档标识
|
||
|
||
| 项目 | 内容 |
|
||
|---|---|
|
||
| 文档标题 (Document Title) | Specification of Crypto Driver(加密驱动规范) |
|
||
| 文档所有者 (Document Owner) | AUTOSAR |
|
||
| 文档责任方 (Document Responsibility) | AUTOSAR |
|
||
| 文档标识号 (Document Identification No) | 807 |
|
||
| 文档状态 (Document Status) | Final |
|
||
| 所属 AUTOSAR 标准 | Classic Platform |
|
||
| 所属标准版本 (Part of Standard Release) | 4.4.0 |
|
||
|
||
## 文档变更历史 (Document Change History)
|
||
|
||
| 日期 | 版本 | 变更者 | 变更描述 |
|
||
|---|---|---|---|
|
||
| 2018-10-31 | 4.4.0 | AUTOSAR Release Management | 移除安全计数器;对齐接口函数的返回值;支持加密驱动内加密操作的源缓冲区和目标缓冲区;支持异步模式下的密钥管理操作 |
|
||
| 2017-12-08 | 4.3.1 | AUTOSAR Release Management | 推出"运行时错误";小修正、澄清和编辑性修订;详细信息请参阅 ChangeDocumentation |
|
||
| 2016-11-30 | 4.3.0 | AUTOSAR Release Management | 初始发布 |
|
||
|
||
---
|
||
|
||
## 目录 (Table of Contents)
|
||
|
||
- [1 引言与功能概述](#1-引言与功能概述)
|
||
- [2 缩略语和缩写](#2-缩略语和缩写)
|
||
- [2.1 术语表](#21-术语表)
|
||
- [3 相关文档](#3-相关文档)
|
||
- [4 约束和假设](#4-约束和假设)
|
||
- [5 对其他模块的依赖](#5-对其他模块的依赖)
|
||
- [6 需求可追溯性](#6-需求可追溯性)
|
||
- [7 功能规范](#7-功能规范)
|
||
- [7.1 预配置](#71-预配置)
|
||
- [7.2 通用行为](#72-通用行为)
|
||
- [7.3 错误分类](#73-错误分类)
|
||
- [8 API 规范](#8-api-规范)
|
||
- [9 序列图](#9-序列图)
|
||
- [10 配置规范](#10-配置规范)
|
||
|
||
---
|
||
|
||
## 1 引言与功能概述
|
||
|
||
本规范规定了 AUTOSAR 基础软件模块 Crypto Driver 的功能、API 和配置。
|
||
|
||
Crypto Driver 位于微控制器抽象层 (Microcontroller Abstraction Layer),位于加密硬件抽象层 (Crypto Interface [4]) 和上层服务层 (Crypto Service Manager [5]) 之下。Crypto Driver 是特定设备的驱动,仅抽象硬件所支持的功能。
|
||
|
||
Crypto Driver 允许定义不同的 Crypto Driver Object(即 AES 加速器、软件组件等),这些对象应用于不同缓冲区中的并发请求。对于每个硬件对象,应支持依赖于优先级的作业处理。加密软件解决方案(即基于软件的 CDD)可以定义与 Crypto Driver 相同的接口以与上层交互,从而为应用程序提供接口。
|
||
|
||
---
|
||
|
||
## 2 缩略语和缩写
|
||
|
||
| 缩写 | 描述 |
|
||
|---|---|
|
||
| CDD | 复杂驱动 (Complex Device Driver) |
|
||
| CSM | 加密服务管理器 (Crypto Service Manager) |
|
||
| CRYIF | 加密接口 (Crypto Interface) |
|
||
| CRYPTO | 加密驱动 (Crypto Driver) |
|
||
| DET | 默认错误追踪器 (Default Error Tracer) |
|
||
| HSM | 硬件安全模块 (Hardware Security Module) |
|
||
| HW | 硬件 (Hardware) |
|
||
| SHE | 安全硬件扩展 (Security Hardware Extension) |
|
||
| SW | 软件 (Software) |
|
||
|
||
### 2.1 术语表
|
||
|
||
| 术语 | 描述 |
|
||
|---|---|
|
||
| Crypto Driver Object (加密驱动对象) | Crypto Driver 实现一个或多个 Crypto Driver Object。Crypto Driver Object 可在硬件或软件中提供不同的加密原语。同一 Crypto Driver 的各 Crypto Driver Object 之间相互独立。每个 Crypto Driver Object 仅有一个工作区(即同一时刻只能执行一种加密原语)。 |
|
||
| Key (密钥) | 密钥可由 CSM 中的作业引用。在 Crypto Driver 中,密钥引用特定的密钥类型。 |
|
||
| Key Type (密钥类型) | 密钥类型由对若干密钥元素的引用构成。密钥类型通常由 Crypto Driver 的供应商预配置。 |
|
||
| Key Element (密钥元素) | 密钥元素用于存储数据。该数据可以是例如密钥材料,或 AES 加密所需的 IV。它也可用于配置密钥管理功能的行为。 |
|
||
| Channel (通道) | 通道是从 CSM 队列经 Crypto Interface 到特定 Crypto Driver Object 的路径。 |
|
||
| Job (作业) | 作业是已配置的加密原语的一个实例。 |
|
||
| Crypto Primitive (加密原语) | 加密原语是已配置的、由 Crypto Driver Object 实现的加密算法的一个实例。 |
|
||
| Operation (操作) | 加密原语的操作声明应执行该加密原语的哪一部分。有三种不同的操作模式: **START**:表示加密原语的全新请求,并应取消同一作业和原语的所有先前请求; **UPDATE**:表示加密原语期望输入数据; **FINISH**:表示在此部分之后所有数据均已完全送入,加密原语可以完成计算。也可以通过将 operation mode 参数的对应位串接在一起,一次执行多个操作。 |
|
||
| Priority (优先级) | 作业的优先级定义其重要性。优先级越高(值越大),作业被越立即地执行。加密作业的优先级是配置的一部分。 |
|
||
|
||
---
|
||
|
||
## 3 相关文档
|
||
|
||
### 3.1 输入文档
|
||
|
||
- [1] AUTOSAR Layered Software Architecture — `AUTOSAR_EXP_LayeredSoftwareArchitecture.pdf`
|
||
- [2] AUTOSAR General Requirements on Basic Software Modules — `AUTOSAR_SRS_BSWGeneral.pdf`
|
||
- [3] AUTOSAR General Specification for Basic Software Modules — `AUTOSAR_SWS_BSWGeneral.pdf`
|
||
- [4] AUTOSAR Specification of Crypto Interface — `AUTOSAR_SWS_CryptoInterface.pdf`
|
||
- [5] AUTOSAR Specification of Crypto Service Manager — `AUTOSAR_SWS_CryptoServiceManager.pdf`
|
||
- [6] AUTOSAR Requirements on Crypto Modules — `AUTOSAR_SRS_CryptoStack.pdf`
|
||
- [7] Glossary — `AUTOSAR_TR_Glossary`
|
||
|
||
### 3.2 相关标准和规范
|
||
|
||
- [8] IEC 7498-1 The Basic Model, IEC Norm, 1994
|
||
|
||
### 3.3 相关规范
|
||
|
||
AUTOSAR 提供了基础软件通用规范 (SWS BSW General) [3],该规范同样适用于 Crypto Driver。因此,SWS BSW General [3] 应被视为 Crypto Driver 的附加且必需的规范。
|
||
|
||
---
|
||
|
||
## 4 约束和假设
|
||
|
||
### 4.1 限制
|
||
|
||
不适用。
|
||
|
||
### 4.2 对汽车域的适用性
|
||
|
||
Crypto Driver 可在需要使用安全功能的所有域应用中使用。
|
||
|
||
---
|
||
|
||
## 5 对其他模块的依赖
|
||
|
||
**[SWS_Crypto_00003]** ⌈ 如果使用片外加密硬件模块(例如外部 HSM),则 Crypto Driver 应使用其他 MCAL 驱动(例如 SPI)的服务。⌋
|
||
|
||
**提示**:如果 Crypto Driver 使用其他 MCAL 驱动(例如 SPI)的服务,则必须确保这些驱动在初始化 Crypto Driver 模块之前已启动并运行。
|
||
|
||
**[SWS_Crypto_00116]** ⌈ 如果专用加密硬件支持,Crypto Driver 应能够以非易失性方式存储密钥材料。⌋
|
||
|
||
**注意**:Crypto Driver 由 Crypto Interface (CRYIF) 调用,CRYIF 是根据加密接口规范 [4] 实现的。Crypto Driver 访问底层硬件和软件对象,以使用其加密原语计算结果。这些结果应转发给 CRYIF。
|
||
|
||
### 5.1 文件结构
|
||
|
||
#### 5.1.1 代码文件结构
|
||
|
||
代码文件结构未在本规范中完整定义。
|
||
|
||
**[SWS_Crypto_00005]** ⌈ 代码文件结构应包含一个源文件 `Crypto.c` 和一个代码文件 `Crypto_KeyManagement.c`。⌋()
|
||
|
||
---
|
||
|
||
## 6 需求可追溯性
|
||
|
||
> 完整可追溯性表(涵盖 SRS_BSW_00101、SRS_BSW_00358、SRS_BSW_00407、SRS_BSW_00414、SRS_CryptoStack_00008、SRS_CryptoStack_00086、SRS_CryptoStack_00098、SWS_BSW_00050、SWS_BSW_00216 等到 SWS_Crypto_xxx 的映射)请参阅原始 PDF 文档第 11 页。
|
||
|
||
---
|
||
|
||
## 7 功能规范
|
||
|
||
Crypto Driver 模块位于微控制器抽象层中,位于 Crypto Interface 模块和 Crypto Service Manager 模块之下。它实现用于同步和异步加密原语的通用接口。它还支持密钥存储、密钥配置以及针对加密服务的密钥管理。
|
||
|
||
为了提供加密功能,ECU 需要集成一个唯一的 Crypto Service Manager 模块和一个 Crypto Interface。但是,Crypto Interface 可以访问多个 Crypto Driver,每个 Crypto Driver 都根据底层 Crypto Driver Object 进行配置。
|
||
|
||
Crypto Driver Object 表示独立加密硬件"设备"的一个实例(例如 AES 加速器)。可以存在用于在 HSM 上对高优先级作业进行快速 AES 和 CMAC 计算的通道,最终指向 Crypto Driver 中的本地 AES 计算服务。但也有可能 Crypto Driver Object 是软件片段,例如用于 RSA 计算的片段,作业能够加密、解密、签名或验证数据。Crypto Driver Object 是加密通道的端点。
|
||
|
||
> **图 7.1:AUTOSAR 分层视图中加密驱动模块**
|
||
|
||
### 7.1 预配置
|
||
|
||
Crypto Driver 的供应商必须为 Crypto Driver 提供预配置,该预配置表示 Crypto Driver 的能力。预配置应随 Crypto Driver 的 BSWMD 文件一起提供。
|
||
|
||
#### 7.1.1 加密能力
|
||
|
||
Crypto Driver 的能力可分为主题:密钥存储和支持的算法。可以通过创建新的 `CryptoPrimitive` 容器(例如 `MacGenerate`)来预配置支持的算法。在此容器中,供应商现在可以指定 Crypto Driver 例如仅能够执行 CMAC。在这种情况下,示例配置为:
|
||
|
||
```text
|
||
CryptoPrimitiveAlgorithmFamily = CRYPTO_ALGOFAM_AES
|
||
CryptoPrimitiveAlgorithmMode = CRYPTO_ALGOMODE_CMAC
|
||
CryptoPrimitiveAlgorithmSecondaryFamily = CRYPTO_ALGOMODE_NOT_SET
|
||
CryptoPrimitiveService = MacGenerate
|
||
```
|
||
|
||
然后可以通过 Crypto Driver Object 引用原语 `MacGenerate`,以表明它能够执行 CMAC。如果没有预配置其他原语,则 Crypto Driver Object 不能执行例如 AES 加密。
|
||
|
||
如果所有原语彼此独立,供应商将为每个原语预配置一个 Crypto Driver Object。否则,将存在一个 Crypto Driver Object,它将引用所有原语。
|
||
|
||
#### 7.1.2 可用密钥
|
||
|
||
Crypto Driver 提供的密钥也可以预配置。`CryptoKey` 容器引用特定的 `CryptoKeyType`。`CryptoKeyType` 提供引用此 `CryptoKeyType` 的 `CryptoKey` 所包含的密钥元素的信息。
|
||
|
||
供应商还预配置密钥元素以定义:
|
||
|
||
- 读/写访问
|
||
- 元素的最大大小
|
||
- 元素是否可以以小于最大大小的数据读/写
|
||
- 如果元素尚未初始化,则启动后的初始化值
|
||
- 元素是否为虚拟元素
|
||
|
||
初始化值是在加密驱动初始化时当密钥元素为空时存储到密钥元素中的值。例如,它用于 id 为 `CRYPTO_KE_<Service>_ALGORITHM` 的密钥元素。通过这种方式,可以配置密钥管理功能。例如,要在一个 Crypto Driver 中提供不同的密钥交换算法,供应商可以预配置以下容器并将 `CRYPTO_KE_<Service>_ALGORITHM` 密钥元素的初始化值设置为供应商特定的值:
|
||
|
||
```text
|
||
CryptoKeyElement_KeyExchange_Algorithm_RSA
|
||
- ID = 11
|
||
- Init value = 0x00
|
||
- Size = 1
|
||
- Read Access = RA_NONE
|
||
- Write Access = WA_NONE
|
||
|
||
CryptoKeyElement_KeyExchange_Algorithm_Ed25519
|
||
- ID = 11
|
||
- Init value = 0x01
|
||
- Size = 1
|
||
- Read Access = RA_NONE
|
||
- Write Access = WA_NONE
|
||
|
||
CryptoKeyType_KeyExchange_RSA
|
||
- CryptoKeyElement_KeyExchange_Algorithm_RSA
|
||
- CryptoKeyElement_KeyExchange_PartnerPubKey
|
||
- CryptoKeyElement_KeyExchange_OwnPubKey
|
||
- CryptoKeyElement_KeyExchange_Base
|
||
- CryptoKeyElement_KeyExchange_PrivKey
|
||
- CryptoKeyElement_KeyExchange_SharedValue
|
||
|
||
CryptoKeyType_KeyExchange_Ed25519
|
||
- CryptoKeyElement_KeyExchange_Algorithm_Ed25519
|
||
- CryptoKeyElement_KeyExchange_PartnerPubKey
|
||
- CryptoKeyElement_KeyExchange_OwnPubKey
|
||
- CryptoKeyElement_KeyExchange_Base
|
||
- CryptoKeyElement_KeyExchange_PrivKey
|
||
- CryptoKeyElement_KeyExchange_SharedValue
|
||
```
|
||
|
||
当应使用类型为 `CryptoKeyType_KeyExchange_Ed25519` 的 `CryptoKey` 执行密钥交换时,Crypto Driver 根据存储在密钥元素 `CRYPTO_KE_KEYEXCHANGE_ALGORITHM` 中的值知道应使用 Ed25519 作为底层加密原语。
|
||
|
||
如果某个密钥应在多个原语中使用,例如 `KeyExchange` 和 `AES-Encrypt-CBC`,则 `CryptoKeyType` 可以通过所需元素进行扩展:
|
||
|
||
```text
|
||
CryptoKeyType_KeyExchange_Cipher_combined
|
||
- CryptoKeyElement_KeyExchange_Algorithm_Ed25519
|
||
- CryptoKeyElement_KeyExchange_PartnerPubKey
|
||
- CryptoKeyElement_KeyExchange_OwnPubKey
|
||
- CryptoKeyElement_KeyExchange_Base
|
||
- CryptoKeyElement_KeyExchange_PrivKey
|
||
- CryptoKeyElement_KeyExchange_SharedValue
|
||
- ID = 1
|
||
- CryptoKeyElement_Cipher_IV
|
||
```
|
||
|
||
注意 `CryptoKeyElement_KeyExchange_SharedValue` 的 id 设置为 1。当使用 `CryptoKeyType_KeyExchange_Cipher_combined` 的密钥调用加密服务时,密钥交换的共享值将自动用作加密密钥。
|
||
|
||
### 7.2 通用行为
|
||
|
||
Crypto Driver 可以具有一个或多个 Crypto Driver Object。
|
||
|
||
**[SWS_Crypto_00012]** ⌈ 如果在一个 ECU 中实现了多个 Crypto Driver 实例(来自相同或不同供应商),则文件名、API 名称和发布参数必须区分开,以避免生成两个同名的定义。
|
||
|
||
名称应按照 `SWS_BSW_00102` 进行格式化:`Crypto_<vi>_<ai>`,其中 `<vi>` 是 `vendorId`,`<ai>` 是 `vendorApiInfix`。⌋()
|
||
|
||
**[SWS_Crypto_00013]** ⌈ Crypto Driver 可以支持底层硬件对象支持的所有加密原语。⌋ (SRS_CryptoStack_00098)
|
||
|
||
CSM 规范 [5] 中声明的作业是已配置的加密原语的一个实例。
|
||
|
||
**[SWS_Crypto_00014]** ⌈ Crypto Driver Object 应仅支持一次处理一个作业。⌋()
|
||
|
||
**[SWS_Crypto_00117]** ⌈ 具有 n 个 Crypto Driver Object 的 Crypto Driver 应能够并行处理 n 个作业。⌋()
|
||
|
||
**提示**:位于作业队列(描述见第 7.2.3.1 章)中的作业不计入正在处理。
|
||
|
||
#### 7.2.1 正常运行
|
||
|
||
**[SWS_Crypto_00017]** ⌈ "START" 表示加密原语的全新请求,并应取消同一作业的所有先前请求。⌋()
|
||
|
||
**注意**:"作业正在处理"意味着相应的 Crypto Driver Object 当前正在主动处理该作业。当作业未完成但 Crypto Driver Object 未主动处理它时(例如因为 "FINISH" 操作尚未完成),这并不意味着该作业正在处理。
|
||
|
||
**注意**:为了统一加密服务的单次调用函数和流式方法,存在一个接口 `Crypto_ProcessJob()`,它带有服务操作参数(嵌入到作业结构参数中)。此服务操作是一个标志字段,指示操作模式 "START"、"UPDATE" 或 "FINISH"。它显式声明将执行哪个操作。如果设置了 "UPDATE" 标志,则加密原语期望输入数据。"FINISH" 指示在此函数调用之后,所有数据都已完全送入,加密原语可以完成计算。这些操作可以组合以一次执行多个操作。然后,按 "START"、"UPDATE"、"FINISH" 的顺序执行操作。
|
||
|
||
一致的单次调用方法可以通过较少的开销提高性能。无需多次调用显式 API,只需一次调用即可。此方法旨在与需要快速处理的小数据输入一起使用。
|
||
|
||
[SWS_Crypto_00018] 中的图显示了此设计的作业状态机(不考虑错误导致的转换)。
|
||
|
||
**[SWS_Crypto_00019]** ⌈ 初始化后,加密驱动处于"idle"状态。⌋()
|
||
|
||
**[SWS_Crypto_00020]** ⌈ 如果在 "Idle" 或 "Active" 状态下使用操作模式 "START" 调用 `Crypto_ProcessJob()`,则应取消先前的请求。也就是说,应重置此作业先前缓冲的所有数据,并且作业应切换到 "Active" 状态并处理新的请求。⌋()
|
||
|
||
**注意**:仅当作业未主动处理时,才可以使用 "START" 重置作业。
|
||
|
||
**[SWS_Crypto_00118]** ⌈ 如果在作业处于 "Idle" 状态时调用 `Crypto_ProcessJob()` 并且操作模式中未设置 "START" 标志,则函数应返回 `E_NOT_OK`。⌋()
|
||
|
||
**注意**:如果在 "Active" 状态下使用操作模式 "UPDATE" 调用 `Crypto_ProcessJob()`,则加密原语被送入输入数据。在任意数量用户数据的流式传输中,使用操作模式 "UPDATE" 多次调用以将更多输入数据馈送到先前的输入数据。在 "Update" 状态下,通常还会计算加密原语的中间结果。实际上,在某些情况下(例如 CBC 模式下的 AES 加密)也存在输出数据的生成。在使用流式方法("Start"、"Update"、"Finish")进行操作时,Crypto Driver Object 等待进一步的输入("Update"),直到达到 "Finish" 状态。与此同时,不能处理其他作业。
|
||
|
||
**[SWS_Crypto_00023]** ⌈ 如果在 "Active" 状态下使用操作模式 "FINISH" 调用 `Crypto_ProcessJob()`,则应完成加密计算。此时其他数据(即要在 MAC 验证服务上测试的 MAC)应可用,以成功处理此作业。计算结果应存储在输出缓冲区中。处理结束时,Crypto Driver 应切换到 "Idle" 状态。⌋()
|
||
|
||
要使用 `Crypto_ProcessJob()` 单次调用处理加密服务,操作模式 `CRYPTO_OPERATIONMODE_SINGLECALL` 是 3 种模式 "START"、"UPDATE" 和 "FINISH" 的析取(按位或)。
|
||
|
||
**[SWS_Crypto_00025]** ⌈ 如果发生内部错误,则相应作业状态应设置为 "Idle",并且应丢弃所有输入数据和中间结果。⌋()
|
||
|
||
**[SWS_Crypto_00119]** ⌈ 如果在处理异步作业时发生内部错误,则相应作业状态应设置为 "Idle",并且应丢弃所有输入数据和中间结果。此外,应使用适当的错误代码调用回调通知。⌋()
|
||
|
||
#### 7.2.2 功能需求
|
||
|
||
**注意**:作业是同步处理还是异步处理的信息是 `Crypto_JobType` 的一部分。
|
||
|
||
##### 7.2.2.1 同步作业处理
|
||
|
||
**[SWS_Crypto_00026]** ⌈ 当使用同步作业处理时,相应的接口函数应在此函数调用的上下文中同步计算结果。⌋()
|
||
|
||
**[SWS_Crypto_00199]** ⌈ 如果 Crypto Driver 具有队列并且发出了同步作业,且其优先级高于队列中可用的最高优先级,则 Crypto Driver 应禁用从队列处理新作业,直到当前正在处理的作业完成后下一次主函数调用结束。⌋()
|
||
|
||
**注意**:通道可能同时保存异步和同步处理类型的作业。如果是这样,同步作业可能不会被接受处理,即使其作业的优先级高于所有异步作业的优先级。
|
||
|
||
##### 7.2.2.2 异步作业处理
|
||
|
||
**[SWS_Crypto_00027]** ⌈ 如果使用异步作业处理,则接口函数应仅将必要的信息移交给原语。实际计算可以由主函数触发。⌋()
|
||
|
||
**[SWS_Crypto_00028]** ⌈ 对于每个异步请求,Crypto Driver 应通过调用 `CRYIF_CallbackNotification` 函数来通知 CRYIF 作业的完成,并传递作业信息和加密操作的结果。⌋()
|
||
|
||
#### 7.2.3 设计注释
|
||
|
||
Crypto Driver 提供两项服务:(1) 加密服务本身,以及 (2) 密钥管理。
|
||
|
||
##### 7.2.3.1 依赖于优先级的作业队列
|
||
|
||
**[SWS_Crypto_00029]** ⌈ (可选)每个 Crypto Driver Object 都应能够将作业排入队列以依次处理它们。⌋()
|
||
|
||
**[SWS_Crypto_00179]** ⌈ 当加密驱动队列的大小设置为 0 时,Crypto Driver Object 应禁用排队。⌋()
|
||
|
||
**[SWS_Crypto_00030]** ⌈ 队列应根据已配置作业的优先级对作业进行排序。⌋()
|
||
|
||
作业优先级值越高,作业的优先级越高。
|
||
|
||
**[SWS_Crypto_00031]** ⌈ 如果在队列为空且 Crypto Driver Object 不忙时调用 `Crypto_ProcessJob()`,则作业应切换到 'active' 状态并执行加密原语。⌋()
|
||
|
||
**[SWS_Crypto_00032]** ⌈ 如果在队列已满时调用 `Crypto_ProcessJob()`,则函数应返回 `CRYPTO_E_QUEUE_FULL`。⌋()
|
||
|
||
**注意**:必须确保异步作业处理得足够快,以避免同步作业长时间等待。还建议对异步作业使用 `CRYPTO_OPERATIONMODE_SINGLECALL`。
|
||
|
||
**注意**:Crypto Driver Object 可以同时处理具有同步和异步作业处理的不同作业。但是,同步作业处理和作业排队可能不有用。因此,如果选择同步作业处理,则不会使用作业队列,并且仅当 Crypto Driver Object 不忙时才会处理作业。
|
||
|
||
**[SWS_Crypto_00121]** ⌈ 如果在作业处于 "ACTIVE" 状态时调用 `Crypto_ProcessJob()`,则 `Crypto_ProcessJob()` 应检查请求的作业是否与 Crypto Driver Object 中的当前作业匹配,如果匹配,则绕过排队。⌋()
|
||
|
||
这意味着只有具有操作模式 "START" 的作业才应排队。如果具有操作模式 "START" 的作业已完成,则 Crypto Driver Object 正在等待输入。回调函数向被调用方指示应执行 "UPDATE" 或 "FINISH" 调用。
|
||
|
||
**[SWS_Crypto_00033]** ⌈ 如果使用异步作业处理调用 `Crypto_ProcessJob()` 并且队列未满,但 Crypto Driver Object 繁忙,并且作业具有操作模式 "START",则 Crypto Driver Object 应将作业放入队列并返回 `CRYPTO_E_OK`。⌋()
|
||
|
||
**[SWS_Crypto_00034]** ⌈ 如果使用同步作业处理调用 `Crypto_ProcessJob()` 并且队列未满,但 Crypto Driver Object 繁忙,则 Crypto Driver Object 不应将作业排队并返回 `CRYPTO_E_BUSY`。任何队列中都不应放入任何作业。⌋()
|
||
|
||
#### 7.2.4 密钥管理
|
||
|
||
一个密钥由一个或多个密钥元素组成。密钥元素的示例包括密钥材料本身、初始化向量、用于随机数生成的种子状态或 SHE 标准的证明。
|
||
|
||
**[SWS_Crypto_00037]** ⌈ 不同加密服务的不同密钥元素的索引按导入类型表 `SWS_Csm_01022` 中的定义。⌋()
|
||
|
||
**[SWS_Crypto_00038]** ⌈ 密钥具有 "valid" 或 "invalid" 状态。⌋()
|
||
|
||
**[SWS_Crypto_00039]** ⌈ 如果密钥处于 "invalid" 状态,则使用该密钥的加密服务应返回 `CRYPTO_E_KEY_NOT_VALID`。⌋()
|
||
|
||
如果某个密钥(或密钥元素)当前正被加密服务使用,则该密钥的状态必须为 "valid"。当调用 `KeyElementSet()` 时,密钥状态设置为 "invalid"。因此,当前正在运行的作业可能会使用不一致的密钥工作。应用程序负责仅在当前没有原语使用该密钥(元素)时更改密钥。
|
||
|
||
**注意**:将密钥和密钥元素映射到 SHE 硬件功能是可能的,没有任何限制。为了提供遗留软件环境,硬件使用的单个密钥可以放置在由多个密钥引用的密钥元素中。每个密钥还具有对包含标识符的密钥元素的唯一引用。因此,根据此规范实现的驱动可以包装现有的 SHE 软硬件,并将数据从密钥元素传递到现有的 SHE 驱动。在此用例中,一个密钥元素可以包含一个计数器,该计数器可由驱动以及应用程序读取和写入。该计数器可用于检测密钥是否被覆盖。将密钥加载到实际硬件密钥槽可以在使用密钥之前立即完成,这将导致密钥的组合加载和处理,以及在将密钥写入密钥元素之后的单独操作。这将导致密钥加载和处理的单独操作。
|
||
|
||
如果要实现新的驱动,也可以使用完全独立的密钥元素配置密钥。这些独立密钥可以存储在 RAM 中,并且仅在操作需要时才传递给硬件密钥槽。驱动中存储的密钥数量可以独立于(且远大于)硬件密钥槽的数量。这当然需要在软件中处理和存储密钥以及所有潜在的缺点。
|
||
|
||
通过调用 `Crypto_KeySetValid` 并将配置参数 `CryptoKeyElementPersist` 设置,可以永久存储密钥。由于在大多数情况下写入操作需要一些时间,因此建议使用 `CRYPTO_KEYSETVALID` 作业接口来永久存储密钥。
|
||
|
||
可以将密钥元素配置为虚拟的。这样,它的行为就像指向存储在另一个元素中的数据的指针。
|
||
|
||
示例是证书。证书数据存储在一个元素中。发行者、证书的公钥和签名等元素仅使用偏移量引用主元素中的数据,而不分配自己的内存。
|
||
|
||
不同的密钥类型可以具有兼容的密钥元素。在这种情况下,`keyElementId` 具有相同的值。具有相同 `keyElementId` 的密钥元素可被视为兼容。通过这种方式,同一密钥可用于不同的服务。因此,密钥材料的 `keyElementId` 应始终为 1。
|
||
|
||
示例是通过密钥管理接口生成密钥,然后在使用原语(如 `MacGenerate`)中使用同一密钥。
|
||
|
||
密钥元素可能未完全写入。在某些情况下,存储在密钥元素中的数据大小可以变化,例如证书。Crypto Driver 应存储实际写入的数据大小,以供内部使用以及使用 `Crypto_KeyElementGet()` 导出元素。如果密钥元素应允许未完全读取或写入,可以使用 `CryptoKeyElement` 容器中的参数 `CryptoKeyElementAllowPartialAccess` 进行配置。
|
||
|
||
#### 7.2.5 密钥格式
|
||
|
||
**[SWS_Crypto_00184]** ⌈ 带标识符的非对称密钥材料按照 RFC5958 以 ASN.1 格式规定。具有格式说明符 `CRYPTO_KE_FORMAT_BIN_IDENT_PRIVATEKEY_PKCS8` 的密钥材料需遵循以下格式规范:
|
||
|
||
```asn1
|
||
OneAsymmetricKey ::= SEQUENCE {
|
||
version Version,
|
||
KeyAlgorithm KeyAlgorithmIdentifier,
|
||
keyMaterial KeyMaterial,
|
||
attributes* [0] Attributes OPTIONAL,
|
||
...,
|
||
[[2: publicKey* [1] PublicKey OPTIONAL ]],
|
||
...
|
||
}
|
||
```
|
||
|
||
\* 密钥属性和 PublicKey 的可选值目前未在加密驱动中使用,此处列出仅为与 RFC5958 兼容。驱动应容忍提供此信息,但不需要评估其内容。
|
||
|
||
元素的含义如下:
|
||
|
||
```asn1
|
||
Version ::= INTEGER { v1(0), v2(1) } (v1, ..., v2)
|
||
|
||
KeyAlgorithmIdentifier ::= AlgorithmIdentifier
|
||
{ PUBLIC-KEY,
|
||
{ PrivateKeyAlgorithms } }
|
||
|
||
KeyMaterial ::= OCTET STRING
|
||
-- 内容根据密钥的类型而变化,并由其 AlgorithmIdentifier 指定。
|
||
-- KeyAlgorithmIdentifier 定义应应用 KeyMaterial 的哪种格式说明符。
|
||
|
||
AlgorithmIdentifier: 通过其对象标识符 (OID) 标识格式的值。
|
||
```
|
||
|
||
⌋ (SRS_CryptoStack_00008)
|
||
|
||
##### 7.2.5.1 RSA 密钥材料的定义
|
||
|
||
**[SWS_Crypto_00185]** ⌈ 对于 `CRYPTO_KE_FORMAT_BIN_RSA_PRIVATEKEY`,RSA 私钥的参数 'KeyMaterial OCTET STRING' 根据 RFC3447 定义,内容如下:
|
||
|
||
```asn1
|
||
KeyMaterial ::= RSAPrivateKey
|
||
|
||
RSAPrivateKey ::= SEQUENCE {
|
||
version Version,
|
||
modulus INTEGER, -- n
|
||
publicExponent INTEGER, -- e
|
||
privateExponent INTEGER, -- d
|
||
prime1 INTEGER, -- p
|
||
prime2 INTEGER, -- q
|
||
exponent1 INTEGER, -- d mod (p-1)
|
||
exponent2 INTEGER, -- d mod (q-1)
|
||
coefficient INTEGER -- (q 的逆) mod p
|
||
}
|
||
|
||
Version ::= INTEGER { two-prime(0), multi(1) }
|
||
```
|
||
|
||
`RSAPrivateKey` 类型的字段具有以下含义:
|
||
|
||
- `version` 是版本号,用于与本文档的未来修订版兼容。对于本文档的此版本,它应为 0。
|
||
- `modulus` 是模数 n。
|
||
- `publicExponent` 是公钥指数 e。
|
||
- `privateExponent` 是私钥指数 d。
|
||
- `prime1` 是 n 的素数因子 p。
|
||
- `prime2` 是 n 的素数因子 q。
|
||
- `exponent1` 是 d mod (p-1)。
|
||
- `exponent2` 是 d mod (q-1)。
|
||
- `coefficient` 是中国剩余定理系数 q-1 mod p。
|
||
|
||
⌋ (SRS_CryptoStack_00008)
|
||
|
||
**注意**:`prime1`、`prime2`、`exponent1`、`exponent2` 和 `coefficient` 的值是可选的。如果未提供 `prime1`,则列表中的以下值都不应提供。否则,应拒绝该密钥。
|
||
|
||
**[SWS_Crypto_00186]** ⌈ 格式为 `CRYPTO_KE_FORMAT_BIN_RSA_PUBLICKEY` 的 RSA 公钥提供如下:
|
||
|
||
```asn1
|
||
RSAPublicKey ::= BIT_STRING {
|
||
modulus INTEGER, -- n
|
||
publicExponent INTEGER, -- e
|
||
}
|
||
```
|
||
|
||
`RSAPublicKey` 类型的字段具有以下含义:
|
||
|
||
- `modulus` 是模数 n。
|
||
- `publicExponent` 是公钥指数 e。
|
||
|
||
⌋ (SRS_CryptoStack_00008)
|
||
|
||
**[SWS_Crypto_00187]** ⌈ 格式为 `CRYPTO_KE_FORMAT_BIN_IDENT_RSA_PUBLICKEY` 的 RSA 公钥提供如下:
|
||
|
||
```asn1
|
||
PublicKeyInfo ::= SEQUENCE {
|
||
KeyAlgorithmIdentifier ::= AlgorithmIdentifier,
|
||
publicKey ::= RSAPublicKey
|
||
}
|
||
```
|
||
|
||
**说明**:参考 RFC5280 第 4.1 节,`SubjectPublicKeyInfo` 直接遵循上述定义。因此,密钥类型 `CRYPTO_KE_FORMAT_BIN_IDENT_PUBLICKEY` 与 `SubjectPublicKeyInfo` 匹配,`CRYPTO_KE_FORMAT_BIN_RSA_PUBLICKEY` 与该定义中的 `subjectPublicKey` 匹配。⌋ (SRS_CryptoStack_00008)
|
||
|
||
**[SWS_Crypto_00188]** ⌈ RSA 密钥的算法标识符应具有值 `1.2.840.113549.1.1.1`。这对应于 ASN.1 编码的 OID 值 "2A 86 48 86 F7 0D 01 01 01"。每当需要 RSA 的 `AlgorithmIdentifier` 时,都应提供此 OID。换句话说,当密钥具有格式 `CRYPTO_KE_FORMAT_BIN_IDENT_PRIVATEKEY_PKCS8` 或 `CRYPTO_KE_FORMAT_BIN_IDENT_PUBLICKEY` 并用于 RSA 时,`AlgorithmIdentifier` 必须具有此值。
|
||
|
||
**注意**:在某些情况下,NULL 值直接跟随在 OID 之后。因此,在同一序列中紧随此 OID 的值是可选的,应予以容忍。⌋ (SRS_CryptoStack_00008)
|
||
|
||
##### 7.2.5.2 ECC 密钥材料的定义
|
||
|
||
**[SWS_Crypto_00189]** ⌈ 由于缺乏明确且有效的 ECC 密钥标准定义,ECC 的密钥材料定义为 `CRYPTO_KE_FORMAT_BIN_OCTET` 格式的二进制信息。数据长度取决于所分配的曲线操作。⌋ (SRS_CryptoStack_00008)
|
||
|
||
**[SWS_Crypto_00190]** ⌈ NIST 和 Brainpool ECC 曲线的公钥通过其 X 和 Y 坐标提供:
|
||
|
||
```text
|
||
ECC Public Key = Point X | Point Y
|
||
```
|
||
|
||
这些点以小端格式存储。密钥的字节数取决于曲线的实现。
|
||
|
||
**示例**:
|
||
|
||
```text
|
||
NIST curve P(256) public key = X(32) | Y(32)
|
||
NIST curve P(192) public key = X(24) | Y(24)
|
||
```
|
||
|
||
⌋ (SRS_CryptoStack_00008)
|
||
|
||
**[SWS_Crypto_00191]** ⌈ NIST 和 Brainpool ECC 曲线的私钥通过其 X 和 Y 坐标以及附加的标量提供:
|
||
|
||
```text
|
||
ECC Private Key = Point X | Point Y | Scalar
|
||
```
|
||
|
||
点和标量以小端格式存储。
|
||
|
||
**示例**:
|
||
|
||
```text
|
||
Brainpool curve P(256) = X(32) | Y(32) | SCALAR(32)
|
||
```
|
||
|
||
⌋ (SRS_CryptoStack_00008)
|
||
|
||
**[SWS_Crypto_00192]** ⌈ ED25519 的公钥信息包含曲线上的一个点:
|
||
|
||
```text
|
||
ED25519 Public Key = Point X
|
||
```
|
||
|
||
该点以小端格式存储。
|
||
|
||
**示例**:
|
||
|
||
```text
|
||
ED25519 Public Key = X(32)
|
||
```
|
||
|
||
⌋ (SRS_CryptoStack_00008)
|
||
|
||
**[SWS_Crypto_00193]** ⌈ ED25519 的私钥信息包含一个随机常数和曲线上的点 X:
|
||
|
||
```text
|
||
ED25519 Private Key = Seed K | Point X
|
||
```
|
||
|
||
该点和种子以小端格式存储。
|
||
|
||
**示例**:
|
||
|
||
```text
|
||
ED25519 Private Key = Seed K(32) | X(32)
|
||
```
|
||
|
||
⌋ (SRS_CryptoStack_00008)
|
||
|
||
### 7.3 错误分类
|
||
|
||
#### 7.3.1 开发错误
|
||
|
||
**[SWS_Crypto_00040]** 开发错误类型 ⌈
|
||
|
||
| 错误类型 | 相关错误代码 | 值(十六进制) |
|
||
|---|---|---|
|
||
| 在 Crypto Driver 初始化之前调用 API 请求 | CRYPTO_E_UNINIT | 0x00 |
|
||
| Crypto Driver 初始化失败 | CRYPTO_E_INIT_FAILED | 0x01 |
|
||
| 使用无效参数调用 API 请求(无重定向的空指针) | CRYPTO_E_PARAM_POINTER | 0x02 |
|
||
| 使用无效参数调用 API 请求(超出范围) | CRYPTO_E_PARAM_HANDLE | 0x04 |
|
||
| 使用无效参数调用 API 请求(无效值) | CRYPTO_E_PARAM_VALUE | 0x05 |
|
||
|
||
⌋(SRS_CryptoStack_00086)
|
||
|
||
#### 7.3.2 运行时错误
|
||
|
||
**[SWS_Crypto_00194]** 运行时错误类型 ⌈
|
||
|
||
| 错误类型 | 相关错误代码 | 值(十六进制) |
|
||
|---|---|---|
|
||
| 操作的缓冲区太小 | CRYPTO_E_RE_SMALL_BUFFER | 0x00 |
|
||
| 请求的密钥不可用 | CRYPTO_E_RE_KEY_NOT_AVAILABLE | 0x01 |
|
||
| 密钥无法读取 | CRYPTO_E_RE_KEY_READ_FAIL | 0x02 |
|
||
| 熵太低 | CRYPTO_E_RE_ENTROPY_EXHAUSTED | 0x03 |
|
||
|
||
⌋ ()
|
||
|
||
#### 7.3.3 瞬态故障
|
||
|
||
无瞬态故障。
|
||
|
||
#### 7.3.4 生产错误
|
||
|
||
无生产错误。
|
||
|
||
#### 7.3.5 扩展生产错误
|
||
|
||
无扩展生产错误。
|
||
|
||
---
|
||
|
||
## 8 API 规范
|
||
|
||
### 8.1 导入类型
|
||
|
||
本章列出了从以下模块导入的所有类型:
|
||
|
||
**[SWS_Crypto_00042]** 导入的类型 ⌈
|
||
|
||
| 模块 | 头文件 | 导入的类型 |
|
||
|---|---|---|
|
||
| Csm | `<none>` | Crypto_JobInfoType |
|
||
| | `<none>` | Crypto_JobType |
|
||
| | `<none>` | Crypto_VerifyResultType |
|
||
| Std_Types | StandardTypes.h | Std_ReturnType |
|
||
| | StandardTypes.h | Std_VersionInfoType |
|
||
|
||
⌋()
|
||
|
||
加密栈 API 使用 Std_ReturnType 的以下扩展:
|
||
|
||
**[SWS_Crypto_00043]** ⌈
|
||
|
||
| 范围 | 描述 |
|
||
|---|---|
|
||
| `CRYPTO_E_BUSY` = 0x02 | 服务请求失败,因为服务仍然繁忙 |
|
||
| `CRYPTO_E_SMALL_BUFFER` = 0x03 | 服务请求失败,因为提供的缓冲区太小,无法存储结果 |
|
||
| `CRYPTO_E_ENTROPY_EXHAUSTION` = 0x04 | 服务请求失败,因为随机数生成器的熵已用尽 |
|
||
| `CRYPTO_E_QUEUE_FULL` = 0x05 | 服务请求失败,因为队列已满 |
|
||
| `CRYPTO_E_KEY_READ_FAIL` = 0x06 | 服务请求失败,因为不允许提取密钥元素 |
|
||
| `CRYPTO_E_KEY_WRITE_FAIL` = 0x07 | 服务请求失败,因为写入访问失败 |
|
||
| `CRYPTO_E_KEY_NOT_AVAILABLE` = 0x08 | 服务请求失败,因为密钥不可用 |
|
||
| `CRYPTO_E_KEY_NOT_VALID` = 0x09 | 服务请求失败,因为密钥无效 |
|
||
| `CRYPTO_E_KEY_SIZE_MISMATCH` = 0x0A | 服务请求失败,因为密钥大小不匹配 |
|
||
| `CRYPTO_E_JOB_CANCELED` = 0x0C | 服务请求失败,因为作业已被取消 |
|
||
| `CRYPTO_E_KEY_EMPTY` = 0x0D | 服务请求失败,因为源密钥元素未初始化 |
|
||
| Description | -- |
|
||
| Available via | CryIf.h |
|
||
|
||
⌋()
|
||
|
||
**注意**:
|
||
|
||
- `CRYPTO_E_KEY_NOT_AVAILABLE` 表示密钥之前已编程,但当前无法访问(例如,由于调试器连接导致密钥被禁用或参数错误)。
|
||
- `CRYPTO_E_KEY_EMPTY` 表示引用的密钥内容尚未写入且没有默认值(例如,在 SHE 1.1 中,将返回错误代码 `ERC_KEY_EMPTY`,"如果应用程序尝试使用尚未初始化的密钥")。
|
||
|
||
加密栈 API 使用 CSM 模块中的密钥元素索引定义。
|
||
|
||
### 8.2 类型定义
|
||
|
||
**[SWS_Crypto_91016]** ⌈
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| Name | `Crypto_ConfigType` |
|
||
| Type | Structure |
|
||
| Range | implementation specific — 配置数据结构的内容是实现特定的 |
|
||
| Description | CryIf 模块的配置数据结构 |
|
||
| Available via | Crypto.h |
|
||
|
||
⌋ (SWS_BSW_00216)
|
||
|
||
### 8.3 函数定义
|
||
|
||
这是为上层模块提供的函数列表。
|
||
|
||
**[SWS_Crypto_00195]** ⌈ 如果使用太小而无法执行所需操作的缓冲区调用 Crypto API,则应向 DET 报告 `CRYPTO_E_RE_SMALL_BUFFER` 并且不应执行该操作。⌋()
|
||
|
||
#### 8.3.1 通用 API
|
||
|
||
##### 8.3.1.1 Crypto_Init
|
||
|
||
**[SWS_Crypto_91000]** ⌈
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| Service name | `Crypto_Init` |
|
||
| Syntax | `void Crypto_Init(const Crypto_ConfigType* configPtr)` |
|
||
| Service ID[hex] | 0x00 |
|
||
| Sync/Async | Synchronous |
|
||
| Reentrancy | Reentrant |
|
||
| Parameters (in) | `configPtr` — 指向所选配置结构的指针 |
|
||
| Parameters (inout) | None |
|
||
| Parameters (out) | None |
|
||
| Return value | void -- |
|
||
| Description | 初始化 Crypto Driver。 |
|
||
| Available via | Crypto.h |
|
||
|
||
⌋ (SRS_BSW_00101, SRS_BSW_00358, SRS_BSW_00414)
|
||
|
||
**[SWS_Crypto_00215]** ⌈ 配置指针 `configPtr` 应始终为空指针值。⌋ (SWS_BSW_00050)
|
||
|
||
配置指针 `configPtr` 当前未使用,因此应设置为空指针值。
|
||
|
||
**[SWS_Crypto_00198]** ⌈ 如果在 Crypto Driver 初始化期间无法加载持久密钥的值,则 Crypto Driver 应将相应密钥的状态设置为 invalid。⌋()
|
||
|
||
**注意**:在 Crypto Driver 初始化之后以及应用程序启动之前,应用程序应考虑检查已配置密钥的状态,并在密钥状态为 invalid 时实施适当的处理。
|
||
|
||
**[SWS_Crypto_00045]** ⌈ 如果 Crypto Driver 的初始化失败,Crypto 应向 DET 报告 `CRYPTO_E_INIT_FAILED`。⌋()
|
||
|
||
##### 8.3.1.2 Crypto_GetVersionInfo
|
||
|
||
**[SWS_Crypto_91001]** ⌈
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| Service name | `Crypto_GetVersionInfo` |
|
||
| Syntax | `void Crypto_GetVersionInfo(Std_VersionInfoType* versioninfo)` |
|
||
| Service ID[hex] | 0x01 |
|
||
| Sync/Async | Synchronous |
|
||
| Reentrancy | Reentrant |
|
||
| Parameters (in) | `versioninfo` — 指向存储本模块版本信息的位置的指针 |
|
||
| Parameters (inout) | None |
|
||
| Parameters (out) | None |
|
||
| Return value | void -- |
|
||
| Description | 返回本模块的版本信息。 |
|
||
| Available via | Crypto.h |
|
||
|
||
⌋ (SRS_BSW_00407)
|
||
|
||
**[SWS_Crypto_00047]** ⌈ 如果参数 `versioninfo` 为空指针,并且为 Crypto Driver 启用了开发错误检测,则函数 `Crypto_GetVersionInfo` 应向 DET 报告 `CRYPTO_E_PARAM_POINTER`。⌋()
|
||
|
||
#### 8.3.2 作业处理接口
|
||
|
||
##### 8.3.2.1 Crypto_ProcessJob
|
||
|
||
**[SWS_Crypto_91003]** ⌈
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| Service name | `Crypto_ProcessJob` |
|
||
| Syntax | `Std_ReturnType Crypto_ProcessJob(uint32 objectId, Crypto_JobType* job)` |
|
||
| Service ID[hex] | 0x03 |
|
||
| Sync/Async | Sync 或 Async,取决于作业配置 |
|
||
| Reentrancy | Reentrant |
|
||
| Parameters (in) | `objectId` — 保存 Crypto Driver Object 的标识符 |
|
||
| Parameters (inout) | `job` — 指向作业配置的指针。包含与作业和原语相关信息的结构以及指向结果缓冲区的指针。 |
|
||
| Parameters (out) | None |
|
||
| Return value | `Std_ReturnType` — `E_OK`:请求成功;`E_NOT_OK`:请求失败;`CRYPTO_E_BUSY`:请求失败,Crypto Driver Object 繁忙;`CRYPTO_E_KEY_NOT_VALID`:请求失败,密钥无效;`CRYPTO_E_KEY_SIZE_MISMATCH`:请求失败,密钥元素大小错误;`CRYPTO_E_QUEUE_FULL`:请求失败,队列已满;`CRYPTO_E_KEY_READ_FAIL`:服务请求失败,因为不允许提取密钥元素;`CRYPTO_E_KEY_WRITE_FAIL`:服务请求失败,因为写入访问失败;`CRYPTO_E_KEY_NOT_AVAILABLE`:服务请求失败,因为密钥不可用;`CRYPTO_E_ENTROPY_EXHAUSTION`:请求失败,熵已用尽;`CRYPTO_E_SMALL_BUFFER`:提供的缓冲区太小,无法存储结果;`CRYPTO_E_JOB_CANCELED`:服务请求失败,因为同步作业已被取消;`CRYPTO_E_KEY_EMPTY`:由于源密钥元素未初始化而请求失败 |
|
||
| Description | 执行作业参数中配置的加密原语。 |
|
||
| Available via | Crypto.h |
|
||
|
||
⌋()
|
||
|
||
此接口根据作业参数的内容(即加密服务的类型)具有不同的行为。根据此配置,需要设置作业中的其他输入参数,以便成功调用此函数。例如,MAC Generate 加密原语需要一个密钥、要使用的明文以及用于生成 MAC 的缓冲区。
|
||
|
||
**[SWS_Crypto_00057]** ⌈ 如果模块未初始化,并且为 Crypto Driver 启用了开发错误检测,则函数 `Crypto_ProcessJob` 应向 DET 报告 `CRYPTO_E_UNINIT` 并返回 `E_NOT_OK`。⌋()
|
||
|
||
**[SWS_Crypto_00058]** ⌈ 如果参数 `objectId` 超出范围,并且为 Crypto Driver 启用了开发错误检测,则函数 `Crypto_ProcessJob` 应向 DET 报告 `CRYPTO_E_PARAM_HANDLE` 并返回 `E_NOT_OK`。⌋()
|
||
|
||
**[SWS_Crypto_00059]** ⌈ 如果参数 `job` 为空指针,并且为 Crypto Driver 启用了开发错误检测,则函数 `Crypto_ProcessJob` 应向 DET 报告 `CRYPTO_E_PARAM_POINTER` 并返回 `E_NOT_OK`。⌋()
|
||
|
||
**[SWS_Crypto_00064]** ⌈ 如果参数 `job->jobPrimitiveInfo->primitiveInfo->service` 不被 Crypto Driver Object 支持,并且为 Crypto Driver 启用了开发错误检测,则函数 `Crypto_ProcessJob` 应向 DET 报告 `CRYPTO_E_PARAM_HANDLE` 并返回 `E_NOT_OK`。⌋()
|
||
|
||
**[SWS_Crypto_00201]** ⌈ 如果 `service` 设置为密钥管理类服务之一(`CRYPTO_KEYSETVALID`、`CRYPTO_RANDOMSEED`、`CRYPTO_KEYGENERATE`、`CRYPTO_KEYDERIVE`、`CRYPTO_KEYEXCHANGECALCPUBVAL`、`CRYPTO_KEYEXCHANGECALCSECRET`、`CRYPTO_CERTIFICATEPARSE` 或 `CRYPTO_CERTIFICATEVERIFY`),则参数 `job->cryptoKeyId` 必须处于范围内;否则函数 `Crypto_ProcessJob` 应向 DET 报告 `CRYPTO_E_PARAM_HANDLE` 并返回 `E_NOT_OK`。⌋()
|
||
|
||
**[SWS_Crypto_00202]** ⌈ 如果 `service` 设置为 `CRYPTO_KEYDERIVE` 或 `CRYPTO_CERTIFICATEVERIFY`,则参数 `job->cryptoTargetKeyId` 必须处于范围内;否则函数 `Crypto_ProcessJob` 应向 DET 报告 `CRYPTO_E_PARAM_HANDLE` 并返回 `E_NOT_OK`。⌋()
|
||
|
||
**[SWS_Crypto_00065]** ⌈ 如果 `service` 设置为 `CRYPTO_HASH` 或 `CRYPTO_MACGENERATE`,则需要参数 `resultLength`。如果作业的配置结果长度小于所选算法的结果长度,则结果的高有效位应被截断为配置的结果长度。⌋()
|
||
|
||
**[SWS_Crypto_00067]** ⌈ 如果参数 `algorithm`(及其族、密钥长度和模式的变化)不被 Crypto Driver Object 支持,并且为 Crypto Driver 启用了开发错误检测,则函数 `Crypto_ProcessJob` 应向 DET 报告 `CRYPTO_E_PARAM_HANDLE` 并返回 `E_NOT_OK`。⌋()
|
||
|
||
**[SWS_Crypto_00070]** ⌈ 如果需要缓冲区指针作为参数,但它是空指针,则 `Crypto_ProcessJob()` 函数应向 DET 报告 `CRYPTO_E_PARAM_POINTER`(如果为 Crypto Driver 启用了开发错误检测),并返回 `E_NOT_OK`。⌋()
|
||
|
||
**[SWS_Crypto_00142]** ⌈ 如果需要长度指针作为参数,但长度指针指向的值为零,并且为 Crypto Driver 启用了开发错误检测,则 `Crypto_ProcessJob()` 函数应向 DET 报告 `CRYPTO_E_PARAM_VALUE` 并返回 `E_NOT_OK`。⌋()
|
||
|
||
**[SWS_Crypto_00071]** ⌈ 下表指定了 `job.jobPrimitiveInputOutputType` 的不同输入和输出缓冲区在每种操作模式(START/UPDATE/FINISH)下的必需或可选成员:
|
||
|
||
| 服务 | Input | Secondary Input | Tertiary Input | Output | Secondary Output | VerifyPtr | mode |
|
||
|---|---|---|---|---|---|---|---|
|
||
| HASH | UG | -- | -- | F | F | -- | SUF |
|
||
| MACGENERATE | UG | -- | -- | F | F | -- | SUF |
|
||
| MACVERIFY | UG | F | F | -- | -- | F | SUF |
|
||
| ENCRYPT | UG | -- | -- | UF | UF | -- | SUF |
|
||
| DECRYPT | UG | -- | -- | UF | UF | -- | SUF |
|
||
| AEADENCRYPT | UG | F | F | UF | UF | F | SUF |
|
||
| AEADDECRYPT | UG | F | F | F | UF | F | SUF |
|
||
| SIGNATUREGENERATE | UG | -- | -- | F | F | -- | SUF |
|
||
| SIGNATUREVERIFY | UG | F | F | -- | -- | F | SUF |
|
||
| RANDOMGENERATE | -- | -- | -- | F | F | -- | -- |
|
||
|
||
**符号说明**:
|
||
|
||
- `S`:Start 模式中需要的成员
|
||
- `U`:Update 模式中需要的成员
|
||
- `F`:Finish 模式中需要的成员
|
||
- `G`:Finish 模式中可选的成员
|
||
- `**`:在输入重定向的情况下,相应的密钥元素用作输入而不是输入缓冲区
|
||
- `***`:在输出重定向的情况下,相应的密钥元素用作输出而不是输出缓冲区
|
||
|
||
⌋()
|
||
|
||
**[SWS_Crypto_00072]** ⌈ `Crypto_ServiceInfoType` 中列出的除 `CRYPTO_HASH` 和 `CRYPTO_RANDOMGENERATE` 之外的所有加密服务都需要一个表示为密钥标识符的密钥。⌋()
|
||
|
||
**[SWS_Crypto_00073]** ⌈ 下表指定了每种服务的输入/输出缓冲区含义(完整表见原文 PDF 第 33-34 页):
|
||
|
||
- HASH:Input=plaintext,Output=generated hash
|
||
- MACGENERATE:Input=plaintext,Output=generated MAC
|
||
- MACVERIFY:Input=plaintext,Secondary Input=MAC to be verified,VerifyPtr
|
||
- ENCRYPT:Input=plaintext,Output=encrypted ciphertext
|
||
- DECRYPT:Input=ciphertext,Output=decrypted plaintext
|
||
- AEADENCRYPT:Input=plaintext,Secondary Input=associated Data,Tertiary Input=Tag to be verified,Output=encrypted ciphertext,Secondary Output=generated Tag
|
||
- AEADDECRYPT:Input=ciphertext,Secondary Input=associated Data,Tertiary Input=Tag,Output=decrypted Plaintext,VerifyPtr
|
||
- SIGNATUREGENERATE:Input=plaintext,Output=generated signature
|
||
- SIGNATUREVERIFY:Input=plaintext,Secondary Input=signature to be verified,VerifyPtr
|
||
- RANDOMGENERATE:Output=Generated random
|
||
- RANDOMSEED:Input=Seed
|
||
- KEYGENERATE:KeyId
|
||
- KEYDERIVE:KeyId,Target KeyId
|
||
- KEYEXCHANGE_CALCPUBVAL:Secondary Input=Public Value,KeyId
|
||
- KEYEXCHANGE_CALCSECRET:Input=Partner's Public Value,KeyId
|
||
- CERTIFICATEPARSE:KeyId
|
||
- CERTIFICATEVERIFY:Output=VerifyPtr,KeyId,Target KeyId
|
||
- KEYSETVALID:KeyId
|
||
|
||
⌋()
|
||
|
||
如果 Crypto Driver 未检测到错误,则它会使用底层硬件或软件解决方案处理作业中配置的加密服务。
|
||
|
||
**[SWS_Crypto_00134]** ⌈ 如果加密原语需要输入数据,则其内存位置由指针 `job->jobPrimitiveInput.inputPtr` 引用。调用 `Crypto_ProcessJob` 时,此数据的长度存储在 `job->jobPrimitiveInput.inputLength` 中。如果所选加密原语使用 secondary 或 tertiary 输入,则类似地适用。如果输入被重定向到密钥元素,则必须使用相应密钥元素的输入缓冲区。⌋()
|
||
|
||
**[SWS_Crypto_00203]** ⌈ 如果 `job->jobRedirectionInfoRef` 不是 `NULLPTR` 并且配置位设置了输入重定向,则应使用由相应 keyId 和 keyElementId 定位的密钥元素缓冲区。如果允许对输入数据和密钥元素数据进行数据操作,则两者都应处理(密钥元素数据优先)。⌋()
|
||
|
||
**[SWS_Crypto_00135]** ⌈ 如果加密原语需要结果的缓冲区,则其内存位置由指针 `job->jobPrimitiveInput.outputPtr` 引用。调用此函数时,`outputLengthPtr` 应包含关联缓冲区的大小。请求完成后,应存储返回值的实际长度。⌋()
|
||
|
||
**[SWS_Crypto_00136]** ⌈ 如果缓冲区太小,无法存储请求的结果,则应返回 `CRYPTO_E_SMALL_BUFFER`,并且函数还应报告运行时错误 `CRYPTO_E_RE_SMALL_BUFFER`。⌋()
|
||
|
||
**[SWS_Crypto_00204]** ⌈ 如果 `job->jobRedirectionInfoRef` 不是 `NULLPTR` 并且配置位设置了输出重定向,则应使用由相应 keyId 和 keyElementId 定位的密钥元素缓冲区作为输出。密钥元素的长度应根据输出的长度设置。⌋()
|
||
|
||
**[SWS_Crypto_00141]** ⌈ 如果选择了随机数生成器服务并且相应的熵已用尽,则函数应返回 `CRYPTO_E_ENTROPY_EXHAUSTED`。函数 `Crypto_ProcessJob` 还应报告运行时错误 `CRYPTO_E_RE_ENTROPY_EXHAUSTED`。⌋()
|
||
|
||
#### 8.3.3 作业取消接口
|
||
|
||
##### 8.3.3.1 Crypto_CancelJob
|
||
|
||
**[SWS_Crypto_00122]** ⌈
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| Service name | `Crypto_CancelJob` |
|
||
| Syntax | `Std_ReturnType Crypto_CancelJob(uint32 objectId, Crypto_JobInfoType* job)` |
|
||
| Service ID[hex] | 0x0e |
|
||
| Sync/Async | Synchronous |
|
||
| Reentrancy | Reentrant, but not for same Crypto Driver Object |
|
||
| Parameters (in) | `objectId` — 保存 Crypto Driver Object 的标识符 |
|
||
| Parameters (inout) | `job` — 指向作业配置的指针 |
|
||
| Parameters (out) | None |
|
||
| Return value | `Std_ReturnType` — `E_OK`:请求成功,作业已被移除;`E_NOT_OK`:请求失败,无法移除作业;`CRYPTO_E_JOB_CANCELED`:作业已被取消但仍在处理。不会向应用程序返回结果。 |
|
||
| Description | 此接口从队列中移除提供的作业,并在可能的情况下取消作业的处理。 |
|
||
| Available via | Crypto.h |
|
||
|
||
⌋()
|
||
|
||
**[SWS_Crypto_00123]** ⌈ 如果为 Crypto Driver 启用了开发错误检测:函数 `Crypto_CancelJob` 应在模块尚未初始化时引发错误 `CRYPTO_E_UNINIT` 并返回 `E_NOT_OK`。⌋()
|
||
|
||
**[SWS_Crypto_00124]** ⌈ 如果为 Crypto Driver 启用了开发错误检测:函数 `Crypto_CancelJob` 应在参数 `objectId` 超出范围时引发错误 `CRYPTO_E_PARAM_HANDLE` 并返回 `E_NOT_OK`。⌋()
|
||
|
||
**[SWS_Crypto_00125]** ⌈ 如果为 Crypto Driver 启用了开发错误检测:函数 `Crypto_CancelJob` 应在参数 `job` 为空指针时引发错误 `CRYPTO_E_PARAM_POINTER` 并返回 `E_NOT_OK`。⌋()
|
||
|
||
**[SWS_Crypto_00214]** ⌈ 如果 Crypto Driver 未检测到错误并且驱动当前未处理此作业,则服务 `Crypto_CancelJob()` 应返回 `E_OK` 而不进行任何处理。⌋()
|
||
|
||
**[SWS_Crypto_00143]** ⌈ 如果 Crypto Driver 未检测到错误并且驱动能够立即取消作业,则服务 `Crypto_CancelJob()` 应从队列中移除该作业并取消硬件中的作业。如果取消成功,则应返回 `E_OK`,否则应返回 `E_NOT_OK`。⌋()
|
||
|
||
**注意**:特别是硬件实现可能不支持取消。如果调用 `Crypto_CancelJob()` 并且不可能立即取消,则应至少抑制该作业的所有结果和通知。
|
||
|
||
**[SWS_Crypto_00183]** ⌈ 如果 Crypto Driver 未检测到错误并且驱动无法取消作业(例如,由于硬件限制),则服务 `Crypto_CancelJob()` 应返回 `CRYPTO_E_JOB_CANCELED`。⌋()
|
||
|
||
#### 8.3.4 密钥管理接口
|
||
|
||
**注意**:如果要修改的实际密钥元素直接映射到闪存,则调用密钥管理函数时可能会有较大的延迟(同步操作)。
|
||
|
||
**[SWS_Crypto_00145]** ⌈ 如果底层加密硬件不允许在处理作业的同时执行密钥管理函数,则密钥管理函数应在当前作业执行时等待,然后开始密钥管理函数的处理。⌋()
|
||
|
||
**注意**:必须确保作业处理得足够快,以避免密钥管理函数长时间等待。还建议对作业使用 `CRYPTO_OPERATIONMODE_SINGLECALL`。
|
||
|
||
##### 8.3.4.1 密钥设置接口
|
||
|
||
###### 8.3.4.1.1 Crypto_KeyElementSet
|
||
|
||
**[SWS_Crypto_91004]** ⌈
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| Service name | `Crypto_KeyElementSet` |
|
||
| Syntax | `Std_ReturnType Crypto_KeyElementSet(uint32 cryptoKeyId, uint32 keyElementId, const uint8* keyPtr, uint32 keyLength)` |
|
||
| Service ID[hex] | 0x04 |
|
||
| Sync/Async | Synchronous |
|
||
| Reentrancy | Non Reentrant |
|
||
| Parameters (in) | `cryptoKeyId`, `keyElementId`, `keyPtr`, `keyLength` |
|
||
| Parameters (inout) | None |
|
||
| Parameters (out) | None |
|
||
| Return value | `E_OK` / `E_NOT_OK` / `CRYPTO_E_BUSY` / `CRYPTO_E_KEY_WRITE_FAIL` / `CRYPTO_E_KEY_NOT_AVAILABLE` / `CRYPTO_E_KEY_SIZE_MISMATCH` |
|
||
| Description | 将给定的密钥元素字节设置为由 `cryptoKeyId` 标识的密钥。 |
|
||
| Available via | Crypto.h |
|
||
|
||
⌋()
|
||
|
||
**[SWS_Crypto_00075..00079, 00146]** 定义了相应的开发错误检测行为:
|
||
- 未初始化 → `CRYPTO_E_UNINIT`
|
||
- `cryptoKeyId`/`keyElementId` 超出范围 → `CRYPTO_E_PARAM_HANDLE`
|
||
- `keyPtr` 为空指针 → `CRYPTO_E_PARAM_POINTER`
|
||
- `keyLength` 为零 → `CRYPTO_E_PARAM_VALUE`
|
||
- `keyLength` 小于密钥元素大小且不允许部分访问 → `CRYPTO_E_KEY_SIZE_MISMATCH`
|
||
|
||
###### 8.3.4.1.2 Crypto_KeySetValid
|
||
|
||
**[SWS_Crypto_91014]** ⌈
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| Service name | `Crypto_KeySetValid` |
|
||
| Syntax | `Std_ReturnType Crypto_KeySetValid(uint32 cryptoKeyId)` |
|
||
| Service ID[hex] | 0x05 |
|
||
| Sync/Async | Synchronous |
|
||
| Reentrancy | Non Reentrant |
|
||
| Parameters (in) | `cryptoKeyId` — 应设置为有效的密钥的标识符 |
|
||
| Return value | `E_OK` / `E_NOT_OK` / `CRYPTO_E_BUSY` |
|
||
| Description | 将 `cryptoKeyId` 标识的密钥状态设置为 valid。 |
|
||
| Available via | Crypto.h |
|
||
|
||
⌋()
|
||
|
||
**[SWS_Crypto_00196, 00197]** 定义了相应的开发错误检测行为(未初始化 → `CRYPTO_E_UNINIT`,`cryptoKeyId` 超出范围 → `CRYPTO_E_PARAM_HANDLE`)。
|
||
|
||
##### 8.3.4.2 密钥提取接口
|
||
|
||
###### 8.3.4.2.1 Crypto_KeyElementGet
|
||
|
||
**[SWS_Crypto_91006]** ⌈
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| Service name | `Crypto_KeyElementGet` |
|
||
| Syntax | `Std_ReturnType Crypto_KeyElementGet(uint32 cryptoKeyId, uint32 keyElementId, uint8* resultPtr, uint32* resultLengthPtr)` |
|
||
| Service ID[hex] | 0x06 |
|
||
| Sync/Async | Synchronous |
|
||
| Reentrancy | Reentrant |
|
||
| Description | 用于获取由 `cryptoKeyId` 标识的密钥的密钥元素。 |
|
||
| Available via | Crypto.h |
|
||
|
||
⌋()
|
||
|
||
**[SWS_Crypto_00140, 00139, 00085..00090, 00092]** 定义了相应的运行时错误和开发错误检测行为:
|
||
- `CRYPTO_E_KEY_NOT_AVAILABLE` → 还应报告 `CRYPTO_E_RE_KEY_NOT_AVAILABLE`
|
||
- `CRYPTO_E_KEY_READ_FAIL` → 还应报告 `CRYPTO_E_RE_KEY_READ_FAIL`
|
||
- 未初始化 → `CRYPTO_E_UNINIT`
|
||
- `cryptoKeyId`/`keyElementId` 超出范围 → `CRYPTO_E_PARAM_HANDLE`
|
||
- `resultPtr`/`resultLengthPtr` 为空指针 → `CRYPTO_E_PARAM_POINTER`
|
||
- 长度为 0 → `CRYPTO_E_PARAM_VALUE`
|
||
|
||
##### 8.3.4.3 密钥复制接口
|
||
|
||
###### 8.3.4.3.1 Crypto_KeyElementCopy
|
||
|
||
**[SWS_Crypto_00148]** ⌈
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| Service name | `Crypto_KeyElementCopy` |
|
||
| Syntax | `Std_ReturnType Crypto_KeyElementCopy(uint32 cryptoKeyId, uint32 keyElementId, uint32 targetCryptoKeyId, uint32 targetKeyElementId)` |
|
||
| Service ID[hex] | 0x0f |
|
||
| Sync/Async | Synchronous |
|
||
| Description | 将密钥元素复制到同一加密驱动中的另一个密钥元素。 |
|
||
| Available via | Crypto.h |
|
||
|
||
⌋()
|
||
|
||
**[SWS_Crypto_00149..00153]** 定义了相应的开发错误检测行为。
|
||
|
||
###### 8.3.4.3.2 Crypto_KeyElementCopyPartial
|
||
|
||
**[SWS_Crypto_91015]** ⌈
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| Service name | `Crypto_KeyElementCopyPartial` |
|
||
| Syntax | `Std_ReturnType Crypto_KeyElementCopyPartial(uint32 cryptoKeyId, uint32 keyElementId, uint32 keyElementSourceOffset, uint32 keyElementTargetOffset, uint32 keyElementCopyLength, uint32 targetCryptoKeyId, uint32 targetKeyElementId)` |
|
||
| Service ID[hex] | 0x13 |
|
||
| Sync/Async | Synchronous |
|
||
| Description | 将密钥元素的一部分复制到同一加密驱动中的另一个密钥元素。 |
|
||
| Available via | Crypto.h |
|
||
|
||
⌋()
|
||
|
||
**[SWS_Crypto_00205..00211]** 定义了相应的开发错误检测行为(未初始化、超出范围、大小不匹配)。
|
||
|
||
###### 8.3.4.3.3 Crypto_KeyCopy
|
||
|
||
**[SWS_Crypto_00155]** ⌈
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| Service name | `Crypto_KeyCopy` |
|
||
| Syntax | `Std_ReturnType Crypto_KeyCopy(uint32 cryptoKeyId, uint32 targetCryptoKeyId)` |
|
||
| Service ID[hex] | 0x10 |
|
||
| Sync/Async | Synchronous |
|
||
| Description | 将密钥及其所有元素复制到同一加密驱动中的另一个密钥。 |
|
||
| Available via | Crypto.h |
|
||
|
||
⌋()
|
||
|
||
**[SWS_Crypto_00156..00159]** 定义了相应的开发错误检测行为。
|
||
|
||
###### 8.3.4.3.4 Crypto_KeyElementIdsGet
|
||
|
||
**[SWS_Crypto_00160]** ⌈
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| Service name | `Crypto_KeyElementIdsGet` |
|
||
| Syntax | `Std_ReturnType Crypto_KeyElementIdsGet(uint32 cryptoKeyId, uint32* keyElementIdsPtr, uint32* keyElementIdsLengthPtr)` |
|
||
| Service ID[hex] | 0x11 |
|
||
| Sync/Async | Synchronous |
|
||
| Description | 用于检索给定密钥中可用的密钥元素。 |
|
||
| Available via | Crypto.h |
|
||
|
||
⌋()
|
||
|
||
**[SWS_Crypto_00161, 00162]** 定义了相应的开发错误检测行为(未初始化 → `CRYPTO_E_UNINIT`,`cryptoKeyId` 超出范围 → `CRYPTO_E_PARAM_HANDLE`)。
|
||
|
||
**注意**:当 CRYIF 应通过 CRYIF 将整个密钥从一个 Crypto Driver 复制到另一个 Crypto Driver 时,需要此函数。
|
||
|
||
##### 8.3.4.4 密钥生成接口
|
||
|
||
###### 8.3.4.4.1 Crypto_RandomSeed
|
||
|
||
**[SWS_Crypto_91013]** ⌈
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| Service name | `Crypto_RandomSeed` |
|
||
| Syntax | `Std_ReturnType Crypto_RandomSeed(uint32 cryptoKeyId, const uint8* seedPtr, uint32 seedLength)` |
|
||
| Service ID[hex] | 0x0d |
|
||
| Sync/Async | Synchronous |
|
||
| Description | 此函数使用提供的熵源生成内部种子状态。此外,此函数可用于使用新熵更新种子状态。 |
|
||
| Available via | Crypto.h |
|
||
|
||
⌋()
|
||
|
||
**[SWS_Crypto_00128..00131]** 定义了相应的开发错误检测行为。
|
||
|
||
如果 Crypto Driver 未检测到错误,则服务 `Crypto_RandomSeed()` 使用从熵源派生的种子状态喂入给定的密钥。随机生成器的内部状态存储在密钥元素 `CRYPTO_KE_RANDOM_SEED` 中。
|
||
|
||
###### 8.3.4.4.2 Crypto_KeyGenerate
|
||
|
||
**[SWS_Crypto_91007]** ⌈
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| Service name | `Crypto_KeyGenerate` |
|
||
| Syntax | `Std_ReturnType Crypto_KeyGenerate(uint32 cryptoKeyId)` |
|
||
| Service ID[hex] | 0x07 |
|
||
| Sync/Async | Synchronous |
|
||
| Description | 生成新的密钥材料并将其存储在 `cryptoKeyId` 标识的密钥中。 |
|
||
| Available via | Crypto.h |
|
||
|
||
⌋()
|
||
|
||
**[SWS_Crypto_00094, 00095, 00165]** 定义了相应的开发错误检测行为和正常操作行为。
|
||
|
||
##### 8.3.4.5 密钥派生接口
|
||
|
||
###### 8.3.4.5.1 Crypto_KeyDerive
|
||
|
||
**[SWS_Crypto_91008]** ⌈
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| Service name | `Crypto_KeyDerive` |
|
||
| Syntax | `Std_ReturnType Crypto_KeyDerive(uint32 cryptoKeyId, uint32 targetCryptoKeyId)` |
|
||
| Service ID[hex] | 0x08 |
|
||
| Sync/Async | Synchronous |
|
||
| Description | 使用 `cryptoKeyId` 标识的给定密钥中的密钥元素派生新密钥。给定密钥包含 password、salt 的密钥元素。派生的密钥存储在 `targetCryptoKeyId` 标识的密钥的 id 为 1 的密钥元素中。迭代次数在密钥元素 `CRYPTO_KE_KEYDERIVATION_ITERATIONS` 中给出。 |
|
||
| Available via | Crypto.h |
|
||
|
||
⌋()
|
||
|
||
**[SWS_Crypto_00097, 00098, 00180, 00166]** 定义了相应的开发错误检测行为和正常操作行为。
|
||
|
||
密钥派生服务需要 salt 和 password 来派生新密钥。因此,salt 和 password 作为密钥元素存储在 `cryptoKeyId` 引用的密钥中。
|
||
|
||
##### 8.3.4.6 密钥交换接口
|
||
|
||
###### 8.3.4.6.1 Crypto_KeyExchangeCalcPubVal
|
||
|
||
**[SWS_Crypto_91009]** ⌈
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| Service name | `Crypto_KeyExchangeCalcPubVal` |
|
||
| Syntax | `Std_ReturnType Crypto_KeyExchangeCalcPubVal(uint32 cryptoKeyId, uint8* publicValuePtr, uint32* publicValueLengthPtr)` |
|
||
| Service ID[hex] | 0x09 |
|
||
| Sync/Async | Synchronous |
|
||
| Description | 计算密钥交换的公钥值,并将公钥存储在公钥值指针指向的内存位置。 |
|
||
| Available via | Crypto.h |
|
||
|
||
⌋()
|
||
|
||
**[SWS_Crypto_00103..00107, 00167, 00109, 00110]** 定义了相应的开发错误检测行为和正常操作行为。
|
||
|
||
###### 8.3.4.6.2 Crypto_KeyExchangeCalcSecret
|
||
|
||
**[SWS_Crypto_91010]** ⌈
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| Service name | `Crypto_KeyExchangeCalcSecret` |
|
||
| Syntax | `Std_ReturnType Crypto_KeyExchangeCalcSecret(uint32 cryptoKeyId, const uint8* partnerPublicValuePtr, uint32 partnerPublicValueLength)` |
|
||
| Service ID[hex] | 0x0a |
|
||
| Sync/Async | Synchronous |
|
||
| Description | 使用 `cryptoKeyId` 标识的密钥的密钥材料和对方的公钥计算密钥交换的共享密钥。共享密钥作为密钥元素存储在同一密钥中。 |
|
||
| Available via | Crypto.h |
|
||
|
||
⌋()
|
||
|
||
**[SWS_Crypto_00111..00115]** 定义了相应的开发错误检测行为。
|
||
|
||
##### 8.3.4.7 证书接口
|
||
|
||
###### 8.3.4.7.1 Crypto_CertificateParse
|
||
|
||
**[SWS_Crypto_91011]** ⌈
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| Service name | `Crypto_CertificateParse` |
|
||
| Syntax | `Std_ReturnType Crypto_CertificateParse(uint32 cryptoKeyId)` |
|
||
| Service ID[hex] | 0x0b |
|
||
| Sync/Async | Synchronous |
|
||
| Description | 解析存储在密钥元素 `CRYPTO_KE_CERT_DATA` 中的证书数据,并填充密钥元素 `CRYPTO_KE_CERT_SIGNEDDATA`、`CRYPTO_KE_CERT_PARSEDPUBLICKEY` 和 `CRYPTO_KE_CERT_SIGNATURE`。 |
|
||
| Available via | Crypto.h |
|
||
|
||
⌋()
|
||
|
||
**[SWS_Crypto_00168..00170]** 定义了相应的开发错误检测行为和正常操作行为。
|
||
|
||
**注意**:这些密钥元素可以是虚拟的,并使用偏移量指向存储在密钥元素 `CRYPTO_KE_CERT_DATA` 中的证书数据,以节省内存。CRYIF 无法读取或写入该偏移量。
|
||
|
||
###### 8.3.4.7.2 Crypto_CertificateVerify
|
||
|
||
**[SWS_Crypto_00171]** ⌈
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| Service name | `Crypto_CertificateVerify` |
|
||
| Syntax | `Std_ReturnType Crypto_CertificateVerify(uint32 cryptoKeyId, uint32 verifyCryptoKeyId, Crypto_VerifyResultType* verifyPtr)` |
|
||
| Service ID[hex] | 0x12 |
|
||
| Sync/Async | Synchronous |
|
||
| Description | 使用由 `cryptoKeyId` 引用的密钥存储的证书验证由 `verifyCryptoKeyId` 引用的密钥存储的证书。 |
|
||
| Available via | Crypto.h |
|
||
|
||
⌋()
|
||
|
||
**[SWS_Crypto_00172..00178]** 定义了相应的开发错误检测行为和正常操作行为,包括:
|
||
- 时间戳格式不匹配 → `CRYPTO_E_PARAM_HANDLE`
|
||
- 使用 `cryptoKeyId` 引用的密钥的 `CRYPTO_KE_CERT_PARSEDPUBLICKEY` 密钥元素进行签名验证
|
||
- 验证成功后将 `validateCryptoKeyId` 标识的密钥设置为 valid
|
||
|
||
**注意**:该函数还可以通过检查当前时间是否在证书的有效期内,以及 `validateCryptoKeyId` 引用的密钥的发行者是否与 `cryptoKeyId` 引用的密钥中的主题相同,来执行进一步的证书验证。
|
||
|
||
### 8.4 调度函数
|
||
|
||
#### 8.4.1.1 Crypto_MainFunction
|
||
|
||
`Crypto_MainFunction()` 对于异步作业处理是必需的。对于同步作业处理,提供主函数是可选的。
|
||
|
||
**[SWS_Crypto_91012]** ⌈
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| Service name | `Crypto_MainFunction` |
|
||
| Syntax | `void Crypto_MainFunction(void)` |
|
||
| Service ID[hex] | 0x0c |
|
||
| Description | 如果配置了异步作业处理并且存在作业队列,则会周期性调用该函数以处理排队的作业。 |
|
||
| Available via | SchM_Crypto.h |
|
||
|
||
⌋()
|
||
|
||
### 8.5 预期接口
|
||
|
||
本节列出了从其他模块所需的所有接口。
|
||
|
||
#### 8.5.1 与标准软件模块的接口
|
||
|
||
**[SWS_Crypto_00126]** ⌈ Crypto Driver 应使用 AUTOSAR DET 模块进行开发错误通知。⌋()
|
||
|
||
#### 8.5.2 必需接口
|
||
|
||
> 无(在 Crypto Driver 4.4.0 中未定义必需接口)。
|
||
|
||
#### 8.5.3 可选接口
|
||
|
||
> 无(在 Crypto Driver 4.4.0 中未定义可选接口)。
|
||
|
||
---
|
||
|
||
## 9 序列图
|
||
|
||
不适用。
|
||
|
||
---
|
||
|
||
## 10 配置规范
|
||
|
||
第 10.1 章规定 Crypto 模块的结构(容器)和参数。第 10.2 章另外规定 Crypto 模块的发布信息。
|
||
|
||
### 10.1 容器和配置参数
|
||
|
||
以下各章总结了所有配置参数。参数的详细含义在第 7 章和第 8 章中描述。
|
||
|
||
**注意**:配置容器中的 ID 应是连续的、无间隔的,并应从零开始。
|
||
|
||
#### 10.1.1 Crypto
|
||
|
||
| SWS Item | `ECUC_Crypto_00001` |
|
||
|---|---|
|
||
| Module Name | `Crypto` |
|
||
| Module Description | Crypto (CryptoDriver) 模块的配置 |
|
||
| Post-Build Variant Support | false |
|
||
| Supported Config Variants | VARIANT-PRE-COMPILE |
|
||
|
||
| 包含的容器 | 多重性 | 范围 / 依赖 |
|
||
|---|---|---|
|
||
| `CryptoDriverObjects` | 1 | CRYPTO 对象的容器 |
|
||
| `CryptoGeneral` | 1 | 公共配置选项的容器 |
|
||
| `CryptoKeyElements` | 0..1 | 加密密钥元素的容器 |
|
||
| `CryptoKeyTypes` | 0..1 | CRYPTO 密钥类型的容器 |
|
||
| `CryptoKeys` | 0..1 | CRYPTO 密钥的容器 |
|
||
| `CryptoPrimitives` | 0..* | CRYPTO 原语的容器 |
|
||
|
||
#### 10.1.2 CryptoGeneral
|
||
|
||
| SWS Item | `ECUC_Crypto_00002` |
|
||
|---|---|
|
||
| Container Name | `CryptoGeneral` |
|
||
| Description | 公共配置选项的容器 |
|
||
| Post-Build Variant Multiplicity | false |
|
||
| Multiplicity Configuration Class | 预编译时:所有变体;链接时:--;后构建时:-- |
|
||
|
||
**配置参数**
|
||
|
||
`ECUC_Crypto_00006`:
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| Name | `CryptoDevErrorDetect` |
|
||
| Parent Container | `CryptoGeneral` |
|
||
| Description | 启用或禁用开发错误检测和通知。`true`:启用检测和通知;`false`:禁用检测和通知 |
|
||
| Multiplicity | 1 |
|
||
| Type | `EcucBooleanParamDef` |
|
||
| Default value | false |
|
||
| Scope / Dependency | scope: local |
|
||
|
||
`ECUC_Crypto_00040`:
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| Name | `CryptoInstanceId` |
|
||
| Parent Container | `CryptoGeneral` |
|
||
| Description | 加密驱动的实例 ID。当同一 ECU 中使用多个驱动时,此 ID 用于区分多个加密驱动。 |
|
||
| Multiplicity | 1 |
|
||
| Type | `EcucIntegerParamDef` |
|
||
| Range | 0 .. 255 |
|
||
| Default value | -- |
|
||
| Post-Build Variant Value | false |
|
||
| Scope / Dependency | scope: local |
|
||
|
||
`ECUC_Crypto_00038`:
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| Name | `CryptoMainFunctionPeriod` |
|
||
| Parent Container | `CryptoGeneral` |
|
||
| Description | 指定主函数 `Crypto_MainFunction` 的周期(秒)。 |
|
||
| Multiplicity | 0..1 |
|
||
| Type | `EcucFloatParamDef` |
|
||
| Range | ]0 .. INF[ |
|
||
| Default value | -- |
|
||
| Scope / Dependency | scope: local |
|
||
|
||
`ECUC_Crypto_00007`:
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| Name | `CryptoVersionInfoApi` |
|
||
| Parent Container | `CryptoGeneral` |
|
||
| Description | 启用和禁用 API `Crypto_GetVersionInfo()` 可用性的预处理开关。`true`:API `Crypto_GetVersionInfo()` 可用;`false`:API 不可用。 |
|
||
| Multiplicity | 1 |
|
||
| Type | `EcucBooleanParamDef` |
|
||
| Default value | false |
|
||
| Scope / Dependency | scope: local |
|
||
|
||
`ECUC_Crypto_00042`:
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| Name | `CryptoEcucPartitionRef` |
|
||
| Parent Container | `CryptoGeneral` |
|
||
| Description | 将 Crypto 驱动映射到零个或多个 ECUC 分区,以使模块的 API 在该分区中可用。模块将在每个分区中作为独立实例运行。 |
|
||
| | **Tags**:atp.Status=draft |
|
||
| Multiplicity | 0..* |
|
||
| Type | 对 `[EcucPartition]` 的引用 |
|
||
| Post-Build Variant Multiplicity | false |
|
||
| Post-Build Variant Value | false |
|
||
| Scope / Dependency | scope: ECU |
|
||
|
||
不包含子容器。
|
||
|
||
**[SWS_Crypto_00212]** Draft ⌈ Crypto Driver 模块应拒绝带有实现不支持的分区映射的配置。⌋()
|
||
|
||
**[SWS_Crypto_CONSTR_00001]** Draft ⌈ Crypto Driver 模块将在每个分区中作为独立实例运行,这意味着调用的 API 将仅针对调用它的分区。⌋()
|
||
|
||
#### 10.1.3 CryptoDriverObjects
|
||
|
||
| SWS Item | `ECUC_Crypto_00003` |
|
||
|---|---|
|
||
| Container Name | `CryptoDriverObjects` |
|
||
| Description | CRYPTO 对象的容器 |
|
||
| Post-Build Variant Multiplicity | false |
|
||
|
||
| 包含的容器 | 多重性 | 范围 / 依赖 |
|
||
|---|---|---|
|
||
| `CryptoDriverObject` | 0..* | CryptoDriverObject 的配置 |
|
||
|
||
#### 10.1.4 CryptoDriverObject
|
||
|
||
| SWS Item | `ECUC_Crypto_00008` |
|
||
|---|---|
|
||
| Container Name | `CryptoDriverObject` |
|
||
| Description | CryptoDriverObject 的配置 |
|
||
|
||
**配置参数**
|
||
|
||
`ECUC_Crypto_00009`:
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| Name | `CryptoDriverObjectId` |
|
||
| Parent Container | `CryptoDriverObject` |
|
||
| Description | Crypto Driver Object 的标识符。Crypto Driver Object 提供不同的加密原语。 |
|
||
| Multiplicity | 1 |
|
||
| Type | `EcucIntegerParamDef`(为此参数生成符号名称) |
|
||
| Range | 0 .. 4294967295 |
|
||
| Default value | -- |
|
||
| Post-Build Variant Multiplicity | false |
|
||
| Post-Build Variant Value | false |
|
||
| Scope / Dependency | scope: local |
|
||
|
||
`ECUC_Crypto_00019`:
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| Name | `CryptoQueueSize` |
|
||
| Parent Container | `CryptoDriverObject` |
|
||
| Description | Crypto Driver 中队列的大小。定义 Crypto Driver Object 队列中的最大作业数。如果设置为 0,则在 Crypto Driver Object 中禁用排队。 |
|
||
| Multiplicity | 1 |
|
||
| Type | `EcucIntegerParamDef` |
|
||
| Range | 0 .. 4294967295 |
|
||
| Default value | -- |
|
||
| Scope / Dependency | scope: local |
|
||
|
||
`ECUC_Crypto_00043`:
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| Name | `CryptoDriverObjectEcucPartitionRef` |
|
||
| Parent Container | `CryptoDriverObject` |
|
||
| Description | 将加密驱动对象映射到零个或多个 ECUC 分区。引用的 ECUC 分区是 Crypto 驱动映射到的 ECUC 分区的子集。 |
|
||
| | **注意**:诸如 HSM 之类的 CryptoDriverObjects 应仅映射到一个分区。 |
|
||
| | **Tags**:atp.Status=draft |
|
||
| Multiplicity | 0..* |
|
||
| Type | 对 `[EcucPartition]` 的引用 |
|
||
| Post-Build Variant Multiplicity | false |
|
||
| Post-Build Variant Value | false |
|
||
| Scope / Dependency | scope: ECU |
|
||
|
||
`ECUC_Crypto_00018`:
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| Name | `CryptoPrimitiveRef` |
|
||
| Parent Container | `CryptoDriverObject` |
|
||
| Description | 引用 CRYPTO 中的原语。`CryptoPrimitive` 是应使用的加密服务的预配置容器。 |
|
||
| Multiplicity | 1..* |
|
||
|
||
#### 10.1.5 CryptoKeys
|
||
|
||
`CryptoKeys` 容器配置实际的加密密钥。每个密钥包含对密钥类型的引用、密钥元素等。
|
||
|
||
#### 10.1.6 CryptoKey
|
||
|
||
`CryptoKey` 容器表示实际的密钥。它引用一个 `CryptoKeyType`,并包含对若干 `CryptoKeyElement` 的引用。
|
||
|
||
#### 10.1.7 CryptoKeyElements
|
||
|
||
`CryptoKeyElements` 容器是所有已配置密钥元素的集合。
|
||
|
||
#### 10.1.8 CryptoKeyElement
|
||
|
||
`CryptoKeyElement` 容器定义单个密钥元素。它具有以下参数:
|
||
|
||
| 参数 | 描述 |
|
||
|---|---|
|
||
| `CryptoKeyElementId` | 密钥元素的标识符 |
|
||
| `CryptoKeyElementInitValue` | 初始化值 |
|
||
| `CryptoKeyElementSize` | 元素的最大大小 |
|
||
| `CryptoKeyElementReadAccess` | 读访问权限(`RA_NONE`、`RA_ENCRYPTED` 等) |
|
||
| `CryptoKeyElementWriteAccess` | 写访问权限(`WA_NONE`、`WA_ENCRYPTED` 等) |
|
||
| `CryptoKeyElementAllowPartialAccess` | 是否允许部分读/写 |
|
||
| `CryptoKeyElementPersist` | 是否应永久存储 |
|
||
| `CryptoKeyElementFormatRef` | 引用密钥格式说明符(RSA、ECC 等) |
|
||
|
||
#### 10.1.9 CryptoKeyTypes
|
||
|
||
`CryptoKeyTypes` 容器是所有已配置密钥类型的集合。
|
||
|
||
#### 10.1.10 CryptoKeyType
|
||
|
||
`CryptoKeyType` 容器定义密钥类型。它包含对一组 `CryptoKeyElement` 的引用。
|
||
|
||
#### 10.1.11 CryptoPrimitives
|
||
|
||
`CryptoPrimitives` 容器是所有已配置加密原语的集合。
|
||
|
||
#### 10.1.12 CryptoPrimitive
|
||
|
||
`CryptoPrimitive` 容器定义单个加密原语(例如 `MacGenerate`)。它具有以下参数:
|
||
|
||
| 参数 | 描述 |
|
||
|---|---|
|
||
| `CryptoPrimitiveService` | 服务类型(HASH、MACGENERATE、ENCRYPT、DECRYPT 等) |
|
||
| `CryptoPrimitiveAlgorithmFamily` | 算法族(AES、SHA、RSA、ECC 等) |
|
||
| `CryptoPrimitiveAlgorithmMode` | 算法模式(ECB、CBC、CMAC 等) |
|
||
| `CryptoPrimitiveAlgorithmSecondaryFamily` | 二级算法族 |
|
||
| `CryptoPrimitiveAlgorithmKeyLength` | 密钥长度 |
|
||
| `CryptoPrimitiveAlgorithmSecondaryAlgorithmLength` | 二级算法长度 |
|
||
| `CryptoPrimitiveRef` | 对其他原语的引用 |
|
||
|
||
> 完整配置容器定义请参见原始 PDF 文档第 58-80 页(包含 ECUC 参数定义的完整列表、每个参数的范围、默认值、约束类等)。
|
||
|
||
### 10.2 发布信息
|
||
|
||
发布信息包含由 SW 模块实施者定义的数据,这些数据在模块适配(即配置)到实际硬件/软件环境时不会更改。因此它包含版本和制造商信息。
|
||
|
||
> 完整发布参数定义请参见原始 PDF 文档第 81 页。
|
||
|
||
---
|
||
|
||
## 翻译说明
|
||
|
||
- 本文档为 AUTOSAR SWS 807《Specification of Crypto Driver》(CP 4.4.0) 的中文翻译;
|
||
- 文档标识号:807;
|
||
- 文档共 81 页,已翻译所有 10 个章节,包括完整的 API 规范、所有 25+ 个关键函数声明、配置规范摘要;
|
||
- 保留了所有 AUTOSAR 方框符、API 标识符、模块缩写、算法名、ASN.1 定义和需求 ID;
|
||
- 对于 RSA、ECC 密钥格式定义已完整保留 ASN.1 结构;
|
||
- 重复的 `CRYPTO_E_*` 错误检测需求条目按类型摘要处理;
|
||
- 配置规范(10.1.5-10.1.12 及 10.2)列出主要容器和参数,详细参数定义参见原始 PDF;
|
||
- 翻译以保证技术含义准确为前提,语句尽量贴近 AUTOSAR 中文术语库常用译法。 |