免责声明
本文内容仅限学习使用。所有对 AUTOSAR 标准的解读均基于公开文档(AUTOSAR_SWS_CryptoDriver.pdf 版本 4.3.1)及行业通用实践,不构成任何形式的工程建议。若将文中内容应用于实际项目,请务必以 AUTOSAR 官方发布的最新规范为准,并结合具体芯片厂商(如 NXP、Infineon、ST)提供的 MCAL 实现和参考手册进行验证。因使用不当造成的任何损失,责任由使用者自行承担。


引言:一张图,看懂 Crypto Driver 配置全貌

在 AUTOSAR Classic Platform 中,配置(Configuration) 是将一个通用的 BSW 模块适配到特定 ECU 硬件和软件需求的过程。对于 Crypto Driver 而言,配置尤为关键——因为它直接关系到密钥存储、算法启用、访问控制和安全策略的落地。

您提供的这张配置图(来自 ECUC 模块定义),以简洁的容器树形式,完整呈现了 Crypto Driver 模块的配置骨架:

Crypto (EcuModuleDef)
├── CryptoGeneral (container, 0..1)
├── CryptoDriverObjects (container, 0..*)
├── CryptoKeys (container, 0..1)
├── CryptoKeyElements (container, 0..1)
├── CryptoKeyTypes (container, 0..1)
└── CryptoPrimitives (container, 0..1)

每一个方框都是一个配置容器(EcuParamConfContainerDef),用于组织相关的配置参数。而容器右侧的 lowerMultiplicity / upperMultiplicity 则定义了该容器在最终配置中可出现的次数

这张图是 Crypto Driver 配置的**“基因图谱”**——它规定了你可以配置什么、必须配置什么、以及各配置部分之间的关系。本文将以此为线索,逐一深入每个容器的内涵、内部参数、设计原理和实际应用场景。

在开始详细解析之前,我想先带大家理解一个核心问题:为什么 Crypto Driver 的配置结构如此“分层”?

答案在于关注点分离。一个完整的加密系统,需要同时管理:

  • 算法能力:这个硬件能做什么?(AES 加密?RSA 签名?SHA 哈希?)
  • 执行单元:有几个独立的计算核心?每个核心支持哪些算法?
  • 密钥结构:一个密钥由哪些数据块组成?(密钥材料 + IV + 计数器?)
  • 密钥实例:具体有多少把密钥?每把密钥的 ID 是什么?
  • 全局策略:开发错误检测要不要开?主函数多久跑一次?

这五个关注点,分别对应了图中的五个子容器——CryptoPrimitives 管算法能力,CryptoDriverObjects 管执行单元,CryptoKeyTypes 管密钥结构,CryptoKeyElements 管数据块定义,CryptoKeys 管密钥实例,CryptoGeneral 管全局策略。

理解了这个“分工”,整个配置图就豁然开朗了。


第一章 配置全景:从根容器到六大子模块

1.1 根容器 Crypto

Crypto
(根容器)
lower=0, upper=*

CryptoGeneral
0..1

CryptoDriverObjects
0..*

CryptoKeys
0..1

CryptoKeyElements
0..1

CryptoKeyTypes
0..1

CryptoPrimitives
0..1

关键解读

lowerMultiplicity = 0, upperMultiplicity = * 表示:在 AUTOSAR 的元模型层面,Crypto 模块的定义本身是“可以不存在,也可以有多个”的。但需要注意,这里的 *元模型层面的通用性设计,在实际的 ECU Configuration 中:

  • 如果该 ECU 不需要加密功能,可以完全不配置 Crypto 模块(0 个实例)。
  • 如果该 ECU 需要加密功能,通常只配置一个 Crypto Driver 模块实例。
  • 一个 ECU 同时使用多个加密硬件(如一个内置 HSM 和一个外部加密芯片)的场景比较少见,通常通过一个 Crypto Driver 内的多个 CryptoDriverObject 来管理,而不是配置多个 Crypto Driver 模块实例。

1.2 六大容器的职责分工

容器名称职责多重性通俗类比
CryptoGeneral全局通用配置:开发错误检测、版本信息、主函数周期0…1“公司规章制度”
CryptoDriverObjects定义加密执行单元(硬件加速器/软件库)0…*“厨师团队”
CryptoKeys定义逻辑密钥实例0…1(容器)+ 内部多个“菜谱卡片”
CryptoKeyElements定义最底层的密钥数据存储单元0…1(容器)+ 内部多个“食材仓库”
CryptoKeyTypes定义密钥结构模板0…1(容器)+ 内部多个“菜品配方”
CryptoPrimitives定义加密原语(算法+模式)0…1(容器)+ 内部多个“烹饪技法”

💡 一个常见疑问:为什么 CryptoKeysCryptoKeyElementsCryptoKeyTypesupperMultiplicity 都是 1?难道一个 Crypto Driver 只能配置一组密钥吗?

解答:这里的 upperMultiplicity=1 指的是容器本身最多出现一次,而不是容器内部的元素数量。每个容器内部可以包含多个子元素(如多个 CryptoKey、多个 CryptoKeyElement、多个 CryptoKeyType)。

这种设计将“分类”和“实例”分离——先定义容器(分类),再在容器内定义多个实例。例如,CryptoKeys 容器内可以配置 32 个 CryptoKey 子项,每个代表一个独立的逻辑密钥。

接下来,我们将逐一深入每个容器,剖析其内部参数、设计意图和配置要点。

第二章 CryptoGeneral:全局“神经系统”

2.1 概述

CryptoGeneral 是 Crypto Driver 的全局配置中枢,它存放那些与具体加密算法、密钥无关,但对整个模块行为有统摄作用的参数。图中标明其为 0..1,意味着该容器可选,但若使用 Crypto Driver,通常必须配置(因为其内部参数往往有默认值,但推荐显式配置以确保行为明确)。

2.2 关键配置参数

根据 AUTOSAR 规范 SWS_CryptoDriver 第 10.1.2 节,CryptoGeneral 包含以下关键配置参数:

参数名称类型描述默认值/范围
CryptoDevErrorDetectBoolean开关开发错误检测(DET)报告功能。true 表示启用。—(必须显式配置)
CryptoInstanceIdInteger (0…255)该 Crypto Driver 实例的 ID,用于区分同 ECU 中的多个驱动。
CryptoMainFunctionPeriodFloatCrypto_MainFunction() 的调用周期(秒),用于异步作业处理。0.01(推荐)
CryptoVersionInfoApiBoolean是否启用 Crypto_GetVersionInfo() API。

2.3 设计原理

这些参数看似简单,背后却体现了 AUTOSAR 的可配置性和可移植性设计哲学:

  • 开发错误检测开关:在开发阶段开启,可以捕获 API 调用的非法参数(如空指针、越界 ID),报告给 DET 模块;在量产阶段关闭,以节省 CPU 资源和代码体积。这是所有 AUTOSAR BSW 模块的通用模式。
  • 实例 ID:当 ECU 中存在多个 Crypto 硬件(例如一个 AES 加速器和一个 RSA 协处理器)时,每个驱动实例拥有不同的 ID,上层 Crypto Interface 可以通过 ID 路由请求到正确的驱动。
  • 主函数周期:异步作业处理依赖于周期性的 Crypto_MainFunction() 来轮询硬件完成状态并触发回调。该周期需要根据作业实时性要求调整,通常设置为毫秒级。

2.4 配置示例(ARXML 片段)

<ECUC-CONTAINER-VALUE>
    <DEFINITION-REF>/AUTOSAR/EcucDefs/Crypto/CryptoGeneral</DEFINITION-REF>
    <SHORT-NAME>CryptoGeneral_0</SHORT-NAME>
    <PARAMETER-VALUES>
        <ECUC-BOOLEAN-VALUE>
            <DEFINITION-REF>/AUTOSAR/EcucDefs/Crypto/CryptoGeneral/CryptoDevErrorDetect</DEFINITION-REF>
            <VALUE>true</VALUE>
        </ECUC-BOOLEAN-VALUE>
        <ECUC-INTEGER-VALUE>
            <DEFINITION-REF>/AUTOSAR/EcucDefs/Crypto/CryptoGeneral/CryptoInstanceId</DEFINITION-REF>
            <VALUE>0</VALUE>
        </ECUC-INTEGER-VALUE>
        <ECUC-FLOAT-VALUE>
            <DEFINITION-REF>/AUTOSAR/EcucDefs/Crypto/CryptoGeneral/CryptoMainFunctionPeriod</DEFINITION-REF>
            <VALUE>0.005</VALUE>
        </ECUC-FLOAT-VALUE>
        <ECUC-BOOLEAN-VALUE>
            <DEFINITION-REF>/AUTOSAR/EcucDefs/Crypto/CryptoGeneral/CryptoVersionInfoApi</DEFINITION-REF>
            <VALUE>true</VALUE>
        </ECUC-BOOLEAN-VALUE>
    </PARAMETER-VALUES>
</ECUC-CONTAINER-VALUE>

2.5 生成的 C 代码

配置工具会根据上述配置生成 Crypto_Cfg.h

/* Crypto_Cfg.h - 由配置工具生成 */
#ifndef CRYPTO_CFG_H
#define CRYPTO_CFG_H

#define CRYPTO_DEV_ERROR_DETECT      STD_ON
#define CRYPTO_INSTANCE_ID           0u
#define CRYPTO_MAIN_FUNCTION_PERIOD  0.005f
#define CRYPTO_VERSION_INFO_API      STD_ON

#endif /* CRYPTO_CFG_H */

关键洞察CryptoGeneral 中的参数通常属于 Pre-compile 配置,因为它们直接影响模块的行为逻辑(如是否包含错误检查代码),必须在编译时确定。

2.6 关联关系

CryptoGeneral全局性的,它不直接引用其他容器,但它的参数会影响整个 Crypto Driver 的行为。例如,若 CryptoDevErrorDetect 设为 false,即使后续配置中的参数有误,也不会触发 DET 错误报告,这可能导致运行时难以排查的问题——因此在实际项目中,开发阶段通常强制开启。

第三章 CryptoPrimitives:加密原语“字典”

3.1 概述

CryptoPrimitives 容器用于定义该 Crypto Driver 支持哪些加密原语(算法服务)。每个原语(CryptoPrimitive)通过四个维度描述:

  • 服务类型(Service):如 ENCRYPTDECRYPTMAC_GENERATEMAC_VERIFYSIGNATURE_GENERATEHASH 等。
  • 算法族(Algorithm Family):如 CRYPTO_ALGOFAM_AESCRYPTO_ALGOFAM_RSACRYPTO_ALGOFAM_SHA2_256 等。
  • 算法模式(Algorithm Mode):如 CRYPTO_ALGOMODE_CBCCRYPTO_ALGOMODE_CMACCRYPTO_ALGOMODE_GCM 等。
  • 次级算法族(Algorithm Secondary Family):用于更精细的区分,如 EC 曲线名称等。

图中 CryptoPrimitives 容器的多重性为 0..1,意味着该容器可选,但若 Crypto Driver 要提供任何加密服务,则必须至少配置一个 CryptoPrimitive 实例。

3.2 设计原理:从“算法”到“服务”的抽象

AUTOSAR Crypto Stack 将用户请求的“服务”与底层“算法”解耦。上层(如 CSM)通过 Crypto_ServiceInfoType 指定 service(如 MAC_GENERATE),而 Crypto Driver 根据配置的 CryptoPrimitive 来匹配支持的服务和算法组合。

执行

Driver匹配

上层请求

Crypto_ProcessJob(objectId, job)

job->jobPrimitiveInfo->primitiveInfo
service = MAC_GENERATE
algorithm = AES
mode = CMAC

遍历 CryptoPrimitive 列表

service 匹配?

algorithm 匹配?

mode 匹配?

找到匹配的原语
执行加密运算

返回 CRYPTO_E_SMALL_BUFFER

3.3 配置示例:一个 AES-CMAC 原语

<ECUC-CONTAINER-VALUE>
    <DEFINITION-REF>/AUTOSAR/EcucDefs/Crypto/CryptoPrimitives/CryptoPrimitive</DEFINITION-REF>
    <SHORT-NAME>CryptoPrimitive_AES_CMAC</SHORT-NAME>
    <PARAMETER-VALUES>
        <ECUC-ENUMERATION-VALUE>
            <DEFINITION-REF>.../CryptoPrimitiveService</DEFINITION-REF>
            <VALUE>MAC_GENERATE</VALUE>
        </ECUC-ENUMERATION-VALUE>
        <ECUC-ENUMERATION-VALUE>
            <DEFINITION-REF>.../CryptoPrimitiveAlgorithmFamily</DEFINITION-REF>
            <VALUE>CRYPTO_ALGOFAM_AES</VALUE>
        </ECUC-ENUMERATION-VALUE>
        <ECUC-ENUMERATION-VALUE>
            <DEFINITION-REF>.../CryptoPrimitiveAlgorithmMode</DEFINITION-REF>
            <VALUE>CRYPTO_ALGOMODE_CMAC</VALUE>
        </ECUC-ENUMERATION-VALUE>
    </PARAMETER-VALUES>
</ECUC-CONTAINER-VALUE>

3.4 与 CryptoDriverObject 的关联(关键!)

CryptoPrimitive 并不直接被 Crypto 根容器使用,而是被 CryptoDriverObject 通过引用(Reference) 所指向。这意味着:

  • 一个 CryptoDriverObject 可以支持多个原语(通过多个 CryptoPrimitiveRef)。
  • 一个 CryptoPrimitive 可以被多个 CryptoDriverObject 引用(如果多个硬件单元都支持相同算法)。

这种多对多关系允许灵活配置:例如,一个 HSM 加速器支持 AES 和 RSA,而一个软件实现仅支持 SHA,则分别配置不同的 Driver Object,各自引用其支持的原语集。

3.5 多重性深入解析

图中 CryptoPrimitives0..1,但在实际 ECU 配置中,往往至少有一个。其内部的 CryptoPrimitive 子容器(根据规范)的 lowerMultiplicity0upperMultiplicity*,表示可以有任意多个原语。这种设计让驱动可以支持广泛的算法组合。

第四章 CryptoKeyElements:密钥数据的“原子单元”

4.1 概述

CryptoKeyElements 容器定义了所有可用的密钥元素CryptoKeyElement)。它是 Crypto Driver 配置中最底层的存储描述单元,直接对应到物理存储介质(如 HSM 的密钥槽、RAM 缓冲区或 NVM 区域)。

4.2 关键配置参数

根据规范第 10.1.8 节,一个 CryptoKeyElement 包含以下关键配置参数:

参数名称类型描述
CryptoKeyElementIdInteger元素 ID,须全局唯一,通常从 1 开始连续编号。
CryptoKeyElementSizeInteger该元素的最大容量(字节)。
CryptoKeyElementInitValueString初始化填充值(十六进制字符串)。
CryptoKeyElementReadAccessEnum读权限:DENIEDINTERNAL_COPYALLOWEDENCRYPTED
CryptoKeyElementWriteAccessEnum写权限:DENIEDINTERNAL_COPYALLOWEDENCRYPTED
CryptoKeyElementAllowPartialAccessBoolean是否允许读写小于 Size 的数据。
CryptoKeyElementPersistBoolean是否持久化到 NVM。
CryptoKeyElementVirtualTargetRefReference若为虚拟元素,指向实际存储数据的另一个元素。

4.3 设计原理:权限与虚拟化

权限控制是密钥元素的核心安全机制。通过 ReadAccessWriteAccess,可以严格限制密钥材料的暴露范围:

权限值含义适用场景
CRYPTO_RA_DENIED / WA_DENIED密钥元素完全不可从外部读写,仅内部使用硬件专用的密钥(如 HSM 内部密钥)
CRYPTO_RA_ALLOWED / WA_ALLOWED允许明文读写开发阶段或非敏感数据(如 IV)
CRYPTO_RA_ENCRYPTED / WA_ENCRYPTED读写时需加密传输生产环境的安全密钥注入
INTERNAL_COPY允许在同一驱动内复制到其他元素,但不可导出外部密钥派生场景

虚拟元素(Virtual Element) 机制允许通过引用(CryptoKeyElementVirtualTargetRef)指向另一个元素中的某段数据,从而避免数据重复存储。例如,证书的签名、公钥等可以从证书数据元素中通过偏移量引用,无需分配独立空间。

4.4 与 CryptoKeyType 的关系(关键!)

CryptoKeyElement 不是直接归属于某个 CryptoKey,而是通过 CryptoKeyType 来引用CryptoKeyType 定义了一个密钥“模板”,它包含对多个 CryptoKeyElement 的引用,并规定这些元素共同组成一个完整的逻辑密钥。

因此,CryptoKeyElements 容器相当于一个“库”,CryptoKeyType 从中挑选若干元素组成不同的密钥模板。

4.5 多重性与实例化

图中 CryptoKeyElements 容器的多重性为 0..1,但其内部的 CryptoKeyElement 子容器(根据规范)的 lowerMultiplicity0upperMultiplicity*,即可以定义任意数量的密钥元素。在实际项目中,通常每个密钥元素对应一个 HSM 硬件密钥槽或一个 NVM 块。

第五章 CryptoKeyTypes:密钥的“建筑蓝图”

5.1 概述

CryptoKeyTypes 容器定义了密钥类型模板CryptoKeyType)。一个 CryptoKeyType 本质上是一个元素列表,它规定了一个逻辑密钥(CryptoKey)由哪些 CryptoKeyElement 组成,以及它们的排列顺序。

根据规范第 10.1.10 节,CryptoKeyType 的唯一配置参数是 CryptoKeyElementRef——一个或多个对 CryptoKeyElement 的引用。

5.2 设计原理:类型与实例分离

为什么需要 CryptoKeyType?直接让 CryptoKey 引用多个 CryptoKeyElement 不就可以了吗?

答案是复用性和一致性。在实际 ECU 中,可能有数十个逻辑密钥(如用于不同通信通道的会话密钥),它们往往共享相同的“结构”(例如,每个密钥都由一个 128 位密钥材料和一个 64 位 IV 组成)。如果每个密钥都单独指定元素列表,会导致大量重复配置。

有KeyType的设计

KeyType_AES_CBC

KeyMaterial 模板

IV 模板

CryptoKey 1

CryptoKey 2

CryptoKey 3

三个密钥共享一个类型模板
配置简洁,一致性高

无KeyType的设计

CryptoKey 1

KeyMaterial_1

IV_1

CryptoKey 2

KeyMaterial_2

IV_2

CryptoKey 3

KeyMaterial_3

IV_3

每个密钥都要重复配置元素列表
配置冗长,容易出错

通过定义 CryptoKeyType,可以:

  • 将“结构”定义为模板(例如 AES_128_CBC_Key 包含 ID=1 的密钥材料和 ID=2 的 IV)。
  • 创建多个 CryptoKey 实例,每个实例只需引用该模板,并拥有自己的 ID 和派生迭代次数。
  • 简化配置,减少出错。

5.3 实例:一个 AES-CBC 密钥类型

假设我们定义了两个密钥元素:

  • KeyMaterial_AES128(ID=1,Size=16)
  • IV_AES(ID=2,Size=16)

CryptoKeyType 配置为:

<ECUC-CONTAINER-VALUE>
    <DEFINITION-REF>/AUTOSAR/EcucDefs/Crypto/CryptoKeyTypes/CryptoKeyType</DEFINITION-REF>
    <SHORT-NAME>CryptoKeyType_AES_CBC</SHORT-NAME>
    <REFERENCE-VALUES>
        <ECUC-REFERENCE-VALUE>
            <DEFINITION-REF>.../CryptoKeyElementRef</DEFINITION-REF>
            <DESTINATION-REF>.../KeyMaterial_AES128</DESTINATION-REF>
        </ECUC-REFERENCE-VALUE>
        <ECUC-REFERENCE-VALUE>
            <DEFINITION-REF>.../CryptoKeyElementRef</DEFINITION-REF>
            <DESTINATION-REF>.../IV_AES</DESTINATION-REF>
        </ECUC-REFERENCE-VALUE>
    </REFERENCE-VALUES>
</ECUC-CONTAINER-VALUE>

之后,任意一个 CryptoKey 引用该 CryptoKeyType,就会自动拥有这两个密钥元素。

5.4 与 CryptoKey 的关系

CryptoKey 通过 CryptoKeyTypeRef 引用一个 CryptoKeyType,从而“继承”其元素列表。同时,CryptoKey 还可以定义与类型无关的额外属性(如迭代次数、ID 等)。

第六章 CryptoKeys:逻辑密钥的“实例仓库”

6.1 概述

CryptoKeys 容器是所有逻辑密钥(CryptoKey)的集合。每个 CryptoKey 代表一个可供上层(如 CSM)通过 ID 引用的密钥实体。

6.2 关键配置参数

根据规范第 10.1.6 节,CryptoKey 包含以下关键参数:

参数名称类型描述
CryptoKeyIdInteger密钥 ID,用于在 API(如 Crypto_ProcessJob)中标识该密钥。
CryptoKeyDerivationIterationsInteger若该密钥用于派生,指定迭代次数(如 PBKDF2)。
CryptoKeyTypeRefReference引用一个 CryptoKeyType,决定该密钥包含哪些元素。

6.3 设计原理:逻辑与物理分离

CryptoKey 是一个逻辑实体,它本身不直接存储数据,而是通过 CryptoKeyTypeRef 间接关联到物理存储(密钥元素)。这种间接层带来了巨大的灵活性:

  • 多个 CryptoKey 可以引用同一个 CryptoKeyType(即共享相同的元素结构),但每个 CryptoKey 拥有独立的 ID 和元素数据。
  • 一个 CryptoKey 可以在运行时通过密钥管理 API(如 Crypto_KeyElementSet)更新其元素内容,而不影响其他密钥。

6.4 多重性与实际数量

图中 CryptoKeys 容器为 0..1,但内部 CryptoKey 子容器(根据规范)的 lowerMultiplicity0upperMultiplicity*,即可以配置任意数量的密钥。在实际项目中,通常配置数十个密钥,分别用于不同安全域。

6.5 密钥状态管理(补充概念)

虽然状态(valid/invalid)不在配置中定义,但规范要求每个密钥在运行时有状态。当密钥元素被修改后,密钥状态自动变为 invalid,直到上层调用 Crypto_KeySetValid 显式设为 valid。这防止了在密钥更新过程中被意外使用。

Crypto_KeySetValid()

Crypto_KeyElementSet()

Crypto_KeySetValid()

Crypto_KeyInvalidate()

INITIALIZED

VALID

INVALID

第七章 CryptoDriverObjects:加密执行单元的“调度中心”

7.1 概述

CryptoDriverObjects 容器定义了一个或多个 Crypto Driver 对象(CryptoDriverObject。每个 CryptoDriverObject 代表一个独立的加密执行单元,可以是硬件加速器、软件算法库,甚至是外部 HSM 芯片。

7.2 关键配置参数

根据规范第 10.1.4 节,CryptoDriverObject 包含以下配置:

参数名称类型描述
CryptoDriverObjectIdInteger对象 ID,用于 API 中指定目标对象。
CryptoQueueSizeInteger该对象的作业队列大小(0 表示禁用队列)。
CryptoPrimitiveRefReference (1…*)引用该对象支持的加密原语列表。

7.3 设计原理:并行处理与优先级

一个 Crypto Driver 可以包含多个 CryptoDriverObject,每个对象独立处理作业。如果硬件支持并行(如多个加密核),那么不同对象可以同时执行作业,提高吞吐量。

每个对象内部可以有一个优先级队列CryptoQueueSize 指定最大长度)。当对象繁忙时,新作业按优先级排队等待。高优先级作业(数值大)先执行。若队列满,新作业会返回 CRYPTO_E_QUEUE_FULL

同步作业(job->sync = true)不会进入队列,而是直接尝试执行;若对象繁忙,则立即返回 CRYPTO_E_BUSY

CryptoDriverObject

先处理优先级10

直接尝试执行
繁忙则返回E_BUSY

作业队列
(按优先级排序)

加密执行单元
(硬件/软件)

作业1(优先级5)

作业2(优先级3)

作业3(优先级10)

同步作业

7.4 与原语的关联

每个 CryptoDriverObject 通过多个 CryptoPrimitiveRef 声明它支持哪些加密服务。当 Crypto_ProcessJob 被调用时,驱动会检查 job 中指定的服务/算法是否匹配该对象的某个原语。如果不匹配,则返回错误。

这种设计允许将不同算法分配到不同硬件单元,实现负载均衡。

7.5 多重性与实际配置

图中 CryptoDriverObjects0..*,即可以有多个对象。典型场景:

  • 一个 ECU 同时拥有一个高速 AES 加速器(对象 1)和一个慢速 RSA 协处理器(对象 2)。上层可根据作业类型选择不同的 objectId
  • 如果仅有一个硬件,则只需配置一个对象,引用所有支持的原语。

第八章 容器间关联:完整的数据流图

现在我们将所有容器及其关联关系绘制成一张完整的架构图:

Crypto

CryptoGeneral
(全局参数)

CryptoDriverObjects
(执行单元集合)

CryptoKeyElements
(数据单元库)

CryptoKeyTypes
(密钥模板库)

CryptoKeys
(逻辑密钥集合)

CryptoPrimitives
(算法原语库)

CryptoDriverObject #1

CryptoPrimitiveRef 1..*

CryptoKeyType #1

CryptoKeyElementRef 1..*

CryptoKey #1

CryptoKeyTypeRef 1

关键关联路径

  1. 算法支持链CryptoDriverObjectCryptoPrimitiveRefCryptoPrimitive。这条链决定了某个执行单元能处理哪些类型的作业。
  2. 密钥结构链CryptoKeyCryptoKeyTypeRefCryptoKeyTypeCryptoKeyElementRefCryptoKeyElement。这条链决定了逻辑密钥的底层数据布局。
  3. 作业路由:上层调用 Crypto_ProcessJob(objectId, job) 时,驱动根据 objectId 找到对应的 CryptoDriverObject,然后检查 job 中的服务/算法是否在其支持的 CryptoPrimitive 列表中。

这三条链共同构成了 Crypto Driver 配置的核心逻辑。

第九章 实战案例:为网关 ECU 配置 Crypto Driver

以下案例为完全虚构,所有时间、地点、人物、公司名称均为杜撰,旨在通过一个典型场景说明配置概念的实际应用,避免任何误导。

场景:假设我们为一家名为“AutoSec Technologies”的供应商(虚构)开发一个网关 ECU,该 ECU 集成了一颗拥有 HSM 的 MCU(例如英飞凌 AURIX TC3xx)。网关需要支持以下安全功能:

  1. 使用 AES-128-CBC 加密/解密 CAN 报文。
  2. 使用 AES-CMAC 生成消息认证码。
  3. 存储两个长期密钥(用于生产加密)和四个会话密钥(运行时生成)。
  4. 支持密钥派生(PBKDF2)用于从主密钥派生会话密钥。

9.1 确定配置结构

首先,我们按照图中的容器结构构建配置文件:

  • CryptoGeneral:启用开发错误检测,实例 ID 设为 0,主函数周期 0.005 秒。
  • CryptoPrimitives:定义三个原语——AES-CBC 加密、AES-CBC 解密、AES-CMAC 生成。
  • CryptoKeyElements:定义两个元素——一个 128 位密钥材料(ID=1),一个 128 位 IV(ID=2)。
  • CryptoKeyTypes:定义一个类型 KeyType_AES_CBC,包含 ID=1 和 ID=2 的元素。
  • CryptoKeys:定义六个密钥——LongTermKey1LongTermKey2SessionKey1~SessionKey4,均引用 KeyType_AES_CBC
  • CryptoDriverObjects:定义一个对象(HSM),引用上述三个原语。

9.2 配置细节示例(ARXML 浓缩版)

<!-- CryptoGeneral -->
<ECUC-CONTAINER-VALUE>
    <DEFINITION-REF>/AUTOSAR/EcucDefs/Crypto/CryptoGeneral</DEFINITION-REF>
    <SHORT-NAME>CryptoGeneral_0</SHORT-NAME>
    <PARAMETER-VALUES>
        <ECUC-BOOLEAN-VALUE>
            <DEFINITION-REF>.../CryptoDevErrorDetect</DEFINITION-REF>
            <VALUE>true</VALUE>
        </ECUC-BOOLEAN-VALUE>
        <ECUC-INTEGER-VALUE>
            <DEFINITION-REF>.../CryptoInstanceId</DEFINITION-REF>
            <VALUE>0</VALUE>
        </ECUC-INTEGER-VALUE>
        <ECUC-FLOAT-VALUE>
            <DEFINITION-REF>.../CryptoMainFunctionPeriod</DEFINITION-REF>
            <VALUE>0.005</VALUE>
        </ECUC-FLOAT-VALUE>
    </PARAMETER-VALUES>
</ECUC-CONTAINER-VALUE>

<!-- CryptoPrimitives -->
<ECUC-CONTAINER-VALUE>
    <DEFINITION-REF>/AUTOSAR/EcucDefs/Crypto/CryptoPrimitives</DEFINITION-REF>
    <SHORT-NAME>CryptoPrimitives_0</SHORT-NAME>
    <SUB-CONTAINERS>
        <ECUC-CONTAINER-VALUE>
            <DEFINITION-REF>.../CryptoPrimitive</DEFINITION-REF>
            <SHORT-NAME>AES_CBC_Encrypt</SHORT-NAME>
            <PARAMETER-VALUES>
                <ECUC-ENUMERATION-VALUE>
                    <DEFINITION-REF>.../CryptoPrimitiveService</DEFINITION-REF>
                    <VALUE>ENCRYPT</VALUE>
                </ECUC-ENUMERATION-VALUE>
                <ECUC-ENUMERATION-VALUE>
                    <DEFINITION-REF>.../CryptoPrimitiveAlgorithmFamily</DEFINITION-REF>
                    <VALUE>CRYPTO_ALGOFAM_AES</VALUE>
                </ECUC-ENUMERATION-VALUE>
                <ECUC-ENUMERATION-VALUE>
                    <DEFINITION-REF>.../CryptoPrimitiveAlgorithmMode</DEFINITION-REF>
                    <VALUE>CRYPTO_ALGOMODE_CBC</VALUE>
                </ECUC-ENUMERATION-VALUE>
            </PARAMETER-VALUES>
        </ECUC-CONTAINER-VALUE>
        <!-- 类似定义 Decrypt 和 CMAC -->
    </SUB-CONTAINERS>
</ECUC-CONTAINER-VALUE>

<!-- CryptoKeyElements -->
<ECUC-CONTAINER-VALUE>
    <DEFINITION-REF>/AUTOSAR/EcucDefs/Crypto/CryptoKeyElements</DEFINITION-REF>
    <SHORT-NAME>CryptoKeyElements_0</SHORT-NAME>
    <SUB-CONTAINERS>
        <ECUC-CONTAINER-VALUE>
            <DEFINITION-REF>.../CryptoKeyElement</DEFINITION-REF>
            <SHORT-NAME>KeyMat_128</SHORT-NAME>
            <PARAMETER-VALUES>
                <ECUC-INTEGER-VALUE>
                    <DEFINITION-REF>.../CryptoKeyElementId</DEFINITION-REF>
                    <VALUE>1</VALUE>
                </ECUC-INTEGER-VALUE>
                <ECUC-INTEGER-VALUE>
                    <DEFINITION-REF>.../CryptoKeyElementSize</DEFINITION-REF>
                    <VALUE>16</VALUE>
                </ECUC-INTEGER-VALUE>
                <ECUC-ENUMERATION-VALUE>
                    <DEFINITION-REF>.../CryptoKeyElementWriteAccess</DEFINITION-REF>
                    <VALUE>CRYPTO_WA_ENCRYPTED</VALUE>
                </ECUC-ENUMERATION-VALUE>
                <ECUC-ENUMERATION-VALUE>
                    <DEFINITION-REF>.../CryptoKeyElementReadAccess</DEFINITION-REF>
                    <VALUE>CRYPTO_RA_DENIED</VALUE>
                </ECUC-ENUMERATION-VALUE>
            </PARAMETER-VALUES>
        </ECUC-CONTAINER-VALUE>
        <ECUC-CONTAINER-VALUE>
            <DEFINITION-REF>.../CryptoKeyElement</DEFINITION-REF>
            <SHORT-NAME>IV_128</SHORT-NAME>
            <PARAMETER-VALUES>
                <ECUC-INTEGER-VALUE>
                    <DEFINITION-REF>.../CryptoKeyElementId</DEFINITION-REF>
                    <VALUE>2</VALUE>
                </ECUC-INTEGER-VALUE>
                <ECUC-INTEGER-VALUE>
                    <DEFINITION-REF>.../CryptoKeyElementSize</DEFINITION-REF>
                    <VALUE>16</VALUE>
                </ECUC-INTEGER-VALUE>
                <ECUC-ENUMERATION-VALUE>
                    <DEFINITION-REF>.../CryptoKeyElementWriteAccess</DEFINITION-REF>
                    <VALUE>CRYPTO_WA_ALLOWED</VALUE>
                </ECUC-ENUMERATION-VALUE>
                <ECUC-ENUMERATION-VALUE>
                    <DEFINITION-REF>.../CryptoKeyElementReadAccess</DEFINITION-REF>
                    <VALUE>CRYPTO_RA_ALLOWED</VALUE>
                </ECUC-ENUMERATION-VALUE>
            </PARAMETER-VALUES>
        </ECUC-CONTAINER-VALUE>
    </SUB-CONTAINERS>
</ECUC-CONTAINER-VALUE>

<!-- CryptoKeyType -->
<ECUC-CONTAINER-VALUE>
    <DEFINITION-REF>/AUTOSAR/EcucDefs/Crypto/CryptoKeyTypes</DEFINITION-REF>
    <SHORT-NAME>CryptoKeyTypes_0</SHORT-NAME>
    <SUB-CONTAINERS>
        <ECUC-CONTAINER-VALUE>
            <DEFINITION-REF>.../CryptoKeyType</DEFINITION-REF>
            <SHORT-NAME>KeyType_AES_CBC</SHORT-NAME>
            <REFERENCE-VALUES>
                <ECUC-REFERENCE-VALUE>
                    <DEFINITION-REF>.../CryptoKeyElementRef</DEFINITION-REF>
                    <DESTINATION-REF>.../KeyMat_128</DESTINATION-REF>
                </ECUC-REFERENCE-VALUE>
                <ECUC-REFERENCE-VALUE>
                    <DEFINITION-REF>.../CryptoKeyElementRef</DEFINITION-REF>
                    <DESTINATION-REF>.../IV_128</DESTINATION-REF>
                </ECUC-REFERENCE-VALUE>
            </REFERENCE-VALUES>
        </ECUC-CONTAINER-VALUE>
    </SUB-CONTAINERS>
</ECUC-CONTAINER-VALUE>

<!-- CryptoKeys -->
<ECUC-CONTAINER-VALUE>
    <DEFINITION-REF>/AUTOSAR/EcucDefs/Crypto/CryptoKeys</DEFINITION-REF>
    <SHORT-NAME>CryptoKeys_0</SHORT-NAME>
    <SUB-CONTAINERS>
        <ECUC-CONTAINER-VALUE>
            <DEFINITION-REF>.../CryptoKey</DEFINITION-REF>
            <SHORT-NAME>LongTermKey1</SHORT-NAME>
            <PARAMETER-VALUES>
                <ECUC-INTEGER-VALUE>
                    <DEFINITION-REF>.../CryptoKeyId</DEFINITION-REF>
                    <VALUE>1</VALUE>
                </ECUC-INTEGER-VALUE>
                <ECUC-INTEGER-VALUE>
                    <DEFINITION-REF>.../CryptoKeyDerivationIterations</DEFINITION-REF>
                    <VALUE>0</VALUE>
                </ECUC-INTEGER-VALUE>
            </PARAMETER-VALUES>
            <REFERENCE-VALUES>
                <ECUC-REFERENCE-VALUE>
                    <DEFINITION-REF>.../CryptoKeyTypeRef</DEFINITION-REF>
                    <DESTINATION-REF>.../KeyType_AES_CBC</DESTINATION-REF>
                </ECUC-REFERENCE-VALUE>
            </REFERENCE-VALUES>
        </ECUC-CONTAINER-VALUE>
        <!-- 类似定义其他5个密钥,ID分别为2~6 -->
    </SUB-CONTAINERS>
</ECUC-CONTAINER-VALUE>

<!-- CryptoDriverObjects -->
<ECUC-CONTAINER-VALUE>
    <DEFINITION-REF>/AUTOSAR/EcucDefs/Crypto/CryptoDriverObjects</DEFINITION-REF>
    <SHORT-NAME>CryptoDriverObjects_0</SHORT-NAME>
    <SUB-CONTAINERS>
        <ECUC-CONTAINER-VALUE>
            <DEFINITION-REF>.../CryptoDriverObject</DEFINITION-REF>
            <SHORT-NAME>HSM_Object</SHORT-NAME>
            <PARAMETER-VALUES>
                <ECUC-INTEGER-VALUE>
                    <DEFINITION-REF>.../CryptoDriverObjectId</DEFINITION-REF>
                    <VALUE>0</VALUE>
                </ECUC-INTEGER-VALUE>
                <ECUC-INTEGER-VALUE>
                    <DEFINITION-REF>.../CryptoQueueSize</DEFINITION-REF>
                    <VALUE>8</VALUE>
                </ECUC-INTEGER-VALUE>
            </PARAMETER-VALUES>
            <REFERENCE-VALUES>
                <ECUC-REFERENCE-VALUE>
                    <DEFINITION-REF>.../CryptoPrimitiveRef</DEFINITION-REF>
                    <DESTINATION-REF>.../AES_CBC_Encrypt</DESTINATION-REF>
                </ECUC-REFERENCE-VALUE>
                <ECUC-REFERENCE-VALUE>
                    <DEFINITION-REF>.../CryptoPrimitiveRef</DEFINITION-REF>
                    <DESTINATION-REF>.../AES_CBC_Decrypt</DESTINATION-REF>
                </ECUC-REFERENCE-VALUE>
                <ECUC-REFERENCE-VALUE>
                    <DEFINITION-REF>.../CryptoPrimitiveRef</DEFINITION-REF>
                    <DESTINATION-REF>.../AES_CMAC_Generate</DESTINATION-REF>
                </ECUC-REFERENCE-VALUE>
            </REFERENCE-VALUES>
        </ECUC-CONTAINER-VALUE>
    </SUB-CONTAINERS>
</ECUC-CONTAINER-VALUE>

9.3 运行时行为

配置完成后,在运行时:

  1. 上层调用 Crypto_ProcessJob(0, job),其中 job->jobPrimitiveInfo->primitiveInfo->service = CRYPTO_ENCRYPT,算法族 AES,模式 CBC,并指定 job->keyId = 1(即 LongTermKey1)。
  2. 驱动检查 objectId=0CryptoDriverObject 是否支持该服务/算法组合(通过其引用的原语列表),确认支持。
  3. 驱动根据 keyId=1 找到 CryptoKey,再通过其 CryptoKeyTypeRef 找到元素列表,获取实际密钥材料和 IV 的存储位置。
  4. 驱动将数据送入 HSM 执行加密,并返回结果。

9.4 配置变更场景

假设后续需求变更,需要支持 AES-GCM,则只需:

  1. CryptoPrimitives 中新增一个 GCM 原语。
  2. CryptoDriverObjectCryptoPrimitiveRef 中添加对该原语的引用。

无需修改密钥定义或上层代码——这正是配置解耦带来的好处。

第十章 配置背后的设计哲学:从“硬编码”到“模型驱动”

10.1 为什么 AUTOSAR 要设计如此复杂的配置结构?

很多初涉 AUTOSAR 的工程师会感叹:“配置比代码还多!” 这种复杂性的背后,是汽车软件开发对可维护性、可移植性和安全性的极致追求。

  • 硬件多样性:不同 ECU 使用不同的加密硬件(内置 HSM、外部安全芯片、纯软件实现)。通过配置(而非代码)来适配硬件,使得同一套 Crypto Driver 源代码可以运行在多种平台上,只需更换配置文件。
  • 安全分级:密钥的访问权限、存储持久化、加密注入等安全策略必须通过配置固化,防止被错误代码绕过。配置即文档,配置即策略。
  • 工具链集成:AUTOSAR 配置模型(EcuC)被设计成可由工具(如 Vector DaVinci、EB tresos)读取和生成,支持图形化配置和自动代码生成,减少人工错误。

10.2 配置的“三层分离”模式

AUTOSAR 将配置分为三个层次(但并非所有模块都支持全部):

配置层次时间点修改方式Crypto Driver 中的典型参数
Pre-compile time编译前修改 _Cfg.h 中的宏CryptoDevErrorDetect
Link time链接时修改 _Lcfg.c 中的常量CryptoKeyElementIdCryptoPrimitiveService
Post-build timeECU 刷写后修改配置数据块密钥材料(实际运行时通过 API 注入,而非静态配置)

Crypto Driver 配置通常采用 Pre-compile 或 Link time,因为密钥元素本身是在运行时通过 API 填充的,而非静态配置。这保证了安全策略的静态固化。

10.3 “引用”的力量:解耦与复用

配置图中的大量 Reference 并非随意设计,而是体现了组合优于继承的软件工程原则:

  • CryptoKeyType 引用 CryptoKeyElement,允许多个密钥类型共享相同的元素定义。
  • CryptoDriverObject 引用 CryptoPrimitive,使一个硬件单元支持多算法,或一个算法被多个硬件单元支持。
  • CryptoKey 引用 CryptoKeyType,使多个密钥实例共享结构。

这种引用关系使得配置高度模块化,修改一处即可影响多处,极大提升维护效率。

10.4 与上层模块的关系

Crypto Driver 的配置不是孤立的——它被上层模块通过 Reference 引用:

  • CSM(Crypto Service Manager) 通过 CsmJob 中的 CsmJobCryptoPrimitiveRef 引用 Crypto Driver 的 CryptoPrimitive
  • CSM 通过 CsmKey 中的 CsmKeyKeyTypeRef 引用 Crypto Driver 的 CryptoKeyType
  • CRYIF(Crypto Interface) 通过 CryIfChannel 中的 CryIfChannelCryptoDriverObjectRef 引用 CryptoDriverObject

这些跨模块引用使得整个 AUTOSAR Crypto Stack 的配置成为一个有机的整体:

CRYPTO

CRYIF

CSM

CsmJobCryptoPrimitiveRef

CsmKeyKeyTypeRef

CryIfChannelCryptoDriverObjectRef

CsmJob

CsmKey

CryIfChannel

CryptoPrimitive

CryptoKeyType

CryptoDriverObject

第十一章 最佳实践与常见陷阱

11.1 最佳实践

实践说明
定义清晰的元素 ID 约定建议将 ID=1 始终用于密钥材料,ID=2 用于 IV,ID=3 用于计数器等。这样在代码中可读性更高。
合理设置访问权限生产环境密钥材料应设置为 DENIED 读取,ENCRYPTED 写入;临时数据(如 IV)可允许明文读写。
谨慎使用虚拟元素虚拟元素节省内存,但增加了理解难度。仅在确实需要共享数据片段时使用,并确保 target 元素已正确配置。
队列大小与作业优先级根据实际负载设定 CryptoQueueSize。如果队列过小,高并发时可能丢作业;过大则浪费内存。
主函数周期适配周期太短增加 CPU 负载,太长影响异步作业响应。推荐根据最坏情况作业执行时间设置,通常为毫秒级。
为每个密钥创建独立的元素虽然共享引用是可能的,但最佳实践是每个 CryptoKey 拥有独立的 CryptoKeyElement 实例,避免运行时修改一个密钥影响另一个。

11.2 常见陷阱

陷阱后果解决建议
忘记配置 CryptoPrimitiveRefCryptoDriverObject 无法处理任何作业确保每个 DriverObject 至少引用一个原语
密钥元素 CryptoKeyElementSize 设置过小运行时写入长度大于 Size 的数据会失败根据实际密钥长度设置,AES-128 为 16,AES-256 为 32
CryptoKeyElementPersist 误设为 true 但硬件不支持 NVM密钥无法持久化,重启后丢失仅当硬件支持且需要长期存储时启用
忘记调用 Crypto_KeySetValid密钥状态一直为 invalid,作业失败在密钥元素写入完成后立即调用
多个 CryptoKey 共享同一个 CryptoKeyType 且共享元素修改一个密钥影响其他密钥为每个密钥创建独立的元素实例

11.3 配置工具的使用提示

大部分 AUTOSAR 配置工具(如 EB tresos、Vector DaVinci)都提供图形化界面,通过拖拽和属性编辑来构建上述配置。你无需手动编写 ARXML,但理解底层结构有助于你在工具的“属性”窗口中快速定位参数。

推荐的配置顺序

  1. 先根据硬件手册确定支持的原语列表,在 CryptoPrimitives 中一一添加。
  2. 再根据 HSM 密钥槽数量,规划 CryptoKeyElements 的数量。
  3. 然后定义 CryptoKeyType,将元素组合成模板。
  4. 接着定义 CryptoKeys,分配 ID 和类型。
  5. 最后定义 CryptoDriverObject,指定 ID、队列大小,并引用所有原语。

这个顺序符合“从底层到顶层”的配置思维。

结语:从蓝图到运行

Crypto Driver 的配置图,就像一座大厦的建筑图纸。它定义了结构(容器)、材料(参数)、连接(引用)和规则(多重性)。当配置完成后,AUTOSAR 代码生成器会将这些蓝图转化为 C 代码中的常量和初始化数据结构,最终在 ECU 运行时,Crypto Driver 按照这些“基因”执行加密任务。

理解这张图,你就掌握了 Crypto Driver 配置的核心骨架。无论你是配置工程师、软件集成师还是架构师,这份知识都将帮助你更自信地进行安全通信、密钥管理和密码运算相关的开发工作。

回顾本文的关键脉络

  • CryptoGeneral 是“公司规章制度”,设置全局开关。
  • CryptoPrimitives 是“烹饪技法”,定义算法能力。
  • CryptoKeyElements 是“食材仓库”,定义数据单元。
  • CryptoKeyTypes 是“菜品配方”,将元素组合成结构。
  • CryptoKeys 是“菜谱卡片”,定义逻辑密钥实例。
  • CryptoDriverObjects 是“厨师团队”,定义执行单元。

六个容器各司其职,通过 Reference 构建关联网络,通过 Multiplicity 约束数量规则,最终形成一套完整的加密服务配置体系。

配置的世界虽复杂,但每一步都有其逻辑和道理。祝你在 AUTOSAR 的海洋中乘风破浪!

参考规范

  • AUTOSAR SWS_CryptoDriver (4.3.1) – Specification of Crypto Driver
  • AUTOSAR TPS_ECUC – ECU Configuration Template Specification
  • AUTOSAR MMOD_ECUC – ECU Configuration Metamodel
  • AUTOSAR SWS_BSWGeneral – General Specification of Basic Software Modules
  • AUTOSAR SRS_CryptoStack – Requirements on Crypto Modules
  • AUTOSAR SWS_CSM – Specification of Crypto Service Manager
  • AUTOSAR SWS_CryptoInterface – Specification of Crypto Interface

更多推荐