文章目录
- Crypto Driver
- Pre-Configuration
- Cryptographic capabilities加密能力
- Available Keys可用密钥
- General Behavior
- Normal Operation
- Functional Requirements
- Synchronous Job Processing
- Asynchronous Job Processing
- Design Notes
- Priority-dependent Job Queue基于优先级的作业队列
- Key Management密钥管理
- Key Formats
- Definition of RSA Key Material
- Error classification错误分类
- Development Errors
- Runtime Errors
- Error detection
Crypto Driver
Crypto Driver属于信息安全协议栈的最下层,与MCU紧密相关,一般Driver由芯片厂商提供(包含在MCAL中),而且一般还会提供对应的Framework(可能是芯片厂商,如NXP,也可能是第三方,如Vector)
Crypto Driver实现了同步和异步 cryptographic primitives的通用接口。它还支持加密服务的密钥存储、密钥配置和密钥管理
Pre-Configuration
Crypto Driver的供应商必须为代表Crypto Driver功能的Crypto Driver提供预配置。预配置应与Crypto Driver的bswmd文件一起交付
Cryptographic capabilities加密能力
Crypto Driver的功能可以分为两个主要主题:密钥存储和支持的算法。可以通过创建一个新的cryptopprimitive容器来预先配置受支持的算法.AES-CMAC算法配置示例如下:
static const Crypto_PrimitiveType Crypto_aPrimitives_CDO_Symmetric[1U] ={{MAC_GENERATE,(uint8)CRYPTO_ALGOFAM_AES,(uint8)CRYPTO_ALGOMODE_CMAC,(uint8)CRYPTO_ALGOFAM_NOT_SET}};
Crypto_PrimitiveType定义如下:
typedef struct
{const Crypto_PrimitiveServiceType eService;const uint8 u8AlgoFamily;const uint8 u8AlgoMode;const uint8 u8SecondaryAlgoFamily;
} Crypto_PrimitiveType;
所有支持的加解密服务都需要通过配置CryptoPrimitives来实现。如果没有配置对应的服务,则驱动不支持对应的算法。
Available Keys可用密钥
由Crypto Driver提供的密钥也可以预配置。一个CryptoKey容器引用一个特定的CryptoKeyType。CryptoKeyType提供了在引用此CryptoKeyType的CryptoKey中包含哪些密钥元素的信息。
供应商还预先配置要定义的关键元素:
-读写权限
-元素的最大大小
-如果该元素可以用小于最大大小的数据进行读写
-如果元素尚未初始化,则启动后的init值
init值就是在初始化加密驱动程序时key元素为空时存储到key元素中的值。例如,它用于id为CRYPTO_KE_<Service>_ALGORITHM的key元素。这样才能配置密钥管理功能。为了在一个加密驱动程序中提供不同的密钥交换算法,供应商可以预先配置以下容器,并将CRYPTO_KE_<Service>_ALGORITHM密钥元素的初始化值设置为供应商特定的值:
CryptoKeyElement_KeyExchange_Algorithm_RSA
- ID = 11
- Init value = 0x00
- Size = 1
- Read Access = RA_NONE
- Write Access = WA_NONE
General Behavior
The Crypto Driver can have one or more Crypto Driver Objects. Driver Objects会关联CryptoPrimitives.
一个 Crypto Driver Object一次只能支持处理一个job。多个Crypto Driver Objects可以同时处理多个job
Normal Operation
调用Start开始运算,调用Update更新数据,调用Finish完成job
要通过使用Crypto_ProcessJob()的单个调用来处理加密服务,操作模式“CRYPTO_OPERATIONMODE_SINGLECALL”是3种模式“START”,“UPDATE”和“FINISH”的分离(按位或)。
Functional Requirements
注意:作业是同步处理还是异步处理的信息是Crypto_JobType的一部分,也就是在JobType中配置,对应的定义为Crypto_ProcessingType。
Synchronous Job Processing
当使用同步作业处理时,相应的接口函数应在此函数调用的上下文中同步计算结果。
如果Crypto Driver有一个队列,并且如果发布了一个 synchronous job,并且优先级大于队列中可用的最高优先级,则Crypto Driver应禁止处理队列中的新作业,直到当前处理的作业完成后,下一次调用main function完成为止。
Asynchronous Job Processing
如果使用异步作业处理,接口函数应该只将必要的信息传递给primitive。实际的计算可能由 main function开始
对于每个异步请求,Crypto Driver应该通过调用CRYIF_CallbackNotification函数来通知CRYIF作业的完成,该函数传递job information和加密操作的结果
Design Notes
Crypto Driver提供两个服务:(1)加密服务本身和(2)密钥管理。
Priority-dependent Job Queue基于优先级的作业队列
(可选)每个Crypto Driver Object都能够将作业排成队列,一个接一个地处理它们。
当Crypto Driver队列的大小设置为0时,加密驱动程序对象应禁用队列。
队列按照配置的作业优先级对作业进行排序。作业优先级值越高,表示作业的优先级越高。
如果调用Crypto_ProcessJob(),当队列为空且Crypto Driver Object不忙时,Job将切换到该状态
’ active '并执行crypto primitive
如果调用Crypto_ProcessJob()并且队列已满,该函数将返回CRYPTO_E_QUEUE_FULL。
注意:必须确保异步作业的处理速度足够快,以避免同步作业必须等待很长时间。还建议对异步作业使用CRYPTO_OPERATIONMODE_SINGLECALL。
注意:一个Crypto Driver Object可以同时处理不同的任务,包括同步和异步任务处理。但是,同步作业处理和作业队列可能没有用处。因此,如果选择同步作业处理,则不会使用作业队列,只有在Crypto Driver Object不忙时才会处理作业。
如果调用了Crypto_ProcessJob()并且Job在“ACTIVE”状态时,Crypto_ProcessJob()将检查请求的作业是否与Crypto Driver Object中的当前作业匹配,如果是,则将其从队列中绕过。
这意味着只有操作模式为“START”的作业才会排队。如果操作模式为“START”的作业已经完成,则Crypto Driver Object 正在等待输入。回调函数指示被调用方应该执行“UPDATE”或“FINISH”调用。
如果异步作业处理调用Crypto_ProcessJob(),且队列未满,但Crypto Driver Object is busy,且作业的操作模式为START,则Crypto Driver Object将该job放入队列并返回E_OK。
如果使用同步作业处理调用Crypto_ProcessJob()并且队列未满,但是Crypto Driver Object is busy,则Crypto Driver Object不将作业排队并返回CRYPTO_E_BUSY。任何作业都不能放在任何队列中
Key Management密钥管理
一个Key由一个或多个Key elements组成。
Key elements的示例包括key本身、初始化向量、随机数生成的种子状态或SHE标准的证明。
每个Key elements都具有定义的读或写访问权限。访问权限本身由具有赋值的枚举定义(参见
[ECUC_Crypto_00024]或[ECUC_Crypto_00027])CryptoKeyElement。
对于访问权限来说,值越小,权限越高。例如CRYPTO_RA_ALLOWED=0为最高权限,
当需要直接访问key elements时,应考虑访问权。这适用于读和写访问
当使用密钥复制接口复制密钥元素时,源密钥元素必须具有比目标密钥元素更高或相同的权限。源密钥必须至少具有以下权限CRYPTO_RA_INTERNAL_COPY或更低的值
信息:只有当key elements位于相同的crypto driver object中时,才能执行internal copy操作。
作业应使用指定的key elements,而不保护密钥访问权限,但以下情况除外:
•如果一个key元素用于使用输入重定向的输入,该key元素必须具有CRYPTO_RA_INTERNAL_COPY或更低的访问权限。如果对CryptoPrimitiveService ENCRYPT/DECRYPT或AEAD_ENCRYPT/AEAD_DECRYPT使用输入重定向,则访问权限必须设置为RA_ENCRYPTED或更低
•如果一个key元素用于输出重定向,该key元素必须具有CRYPTO_WA_INTERNAL_COPY或更低的访问权限。
•使用密钥交换操作生成密钥的任何密钥元素应具有至少CRYPTO_RA_INTERNAL_COPY或更低的访问权限
•对于密钥派生,源密钥的访问权限至少为CRYPTO_RA_INTERNAL_COPY或更低。目标密钥至少具有源密钥的访问权限或更低的访问权限
密钥的状态是“有效”或“无效”。
如果密钥处于“无效”状态,使用该密钥的加密服务将返回CRYPTO_E_KEY_NOT_VALID。
Key Formats
具有标识的非对称密钥材料按照ASN.1格式的RFC5958规定。带格式说明符的关键材料
CRYPTO_KE_FORMAT_BIN_IDENT_PRIVATEKEY_ PKCS8需要遵循以下格式规范:
OneAsymmetricKey ::= SEQUENCE {version Version,KeyAlgorithm KeyAlgorithmIdentifier,keyMaterial KeyMaterial,attributes* [0] Attributes OPTIONAL,...,[[2: publicKey* [1] PublicKey OPTIONAL ]],...}
Version:版本,KeyAlgorithmIdentifier:密钥算法标识,KeyMaterial:密钥值
Definition of RSA Key Material
对于CRYPTO_KE_FORMAT_BIN_ RSA_PRIVATEKEY, RSA私钥的参数’ KeyMaterial OCTET STRING '是根据IETF RFC8017定义的,具有以下内容:
KeyMaterial ::= RSAPrivateKeyRSAPrivateKey ::= SEQUENCE {version Version,modulus INTEGER, -- npublicExponent INTEGER, -- eprivateExponent INTEGER, -- dprime1 INTEGER, -- pprime2 INTEGER, -- qexponent1 INTEGER, -- d mod (p-1)exponent2 INTEGER, -- d mod (q-1)coefficient INTEGER -- (inverse of q) mod p }
“version”为版本号,以确保与本文档未来版本的兼容性。这个版本的文件应该是0。
·模为模n。
•publicExponent为公共指数e。
•privateExponent为私有指数d。
•prime1是n的质因数p。
•prime2是n的质因数q。
•exponent1为d mod (p-1)。
•exponent2为d mod (q-1)。
·系数为e Chinese Remainder Theorem coefficient(q的倒数) mod p
RSA公钥的格式为CRYPTO_KE_FORMAT_BIN _RSA_PUBLICKEY的示例如下:
RSAPublicKey ::= SEQUENCE {modulus INTEGER, -- npublicExponent INTEGER, -- e}
RSAPublicKey类型的字段含义如下:
·模为模n。
•publicExponent为公共指数e。
RSA公钥的格式为CRYPTO_KE_FORMAT_BIN _IDENT_RSA_PUBLICKEY的示例如下:
PublicKeyInfo ::= SEQUENCE {KeyAlgorithmIdentifier ::= AlgorithmIdentifier,publicKey ::= RSAPublicKey}
RSA密钥的算法标识符应该为1.2.840.113549.1.1.1。这对应于ASN.1编码的OID值“2A 86 48 86”
f70d 01 01 01”。
当需要RSA的算法标识符时,应提供此OID。换句话说,当一个密钥具有CRYPTO_KE_FORMAT_BIN_IDENT_PRIVATEKEY_ PKCS8或
CRYPTO_KE_FORMAT_BIN_IDENT_PUBLICKEY且用于RSA时,AlgorithmIdentifier必须有这个值。
Error classification错误分类
Development Errors
Runtime Errors
Error detection
在执行作业之前,加密驱动程序应检查job->cryptoKeyId和(如果适用)job->targetCryptoKeyId是否在范围内。如果检查失败,函数Crypto_ProcessJob将报告CRYPTO_E_PARAM_HANDLE给DET并返回E_NOT_OK
如果调用了Crypto Driver API,且操作过程中寻址的缓冲区太小,则不执行该操作。如果启用了Crypto Driver的开发错误检测,则API函数应向DET报告CRYPTO_E_SMALL_BUFFER,否则返回E_NOT_OK