打印
[STM32L5]

STM32L5 进阶课程 12. PKA, 非对称加解密 加速引擎

[复制链接]
1584|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
powerantone|  楼主 | 2023-11-27 15:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

欢迎大家继续关注STM32L5 线上课程第二季。


这一集,是我们第二季课程的最后一节课,我们介绍STM32L5上集成的安全应用外设:PKA,英文全称是 public key acceleration。


它是一个非对称加解密硬件引擎,又叫做公钥加解密硬件引擎,具有灵活、快速,简便的使用特点。



公钥加解密技术是很多信息安全标准的基石,广泛被用于在开放网络环境中建立安全的通信通道,或者通过电子签名技术提供身份和消息认证服务


由于需要大量计算,基于纯软件的公钥加解密方案,对实时应用来说,速度太慢会影响整个系统的性能;而PKA模块无需CPU参与,使用硬件完成,速度快,功耗低。


PKA模块支持RSA、ECDSA等国际标准非对称加解密技术规范,快速实现设备端的签名、验签,以及非对称加解密操作,无需CPU干预,为IoT时代的安全服务提供硬件加速。



PKA作为一种加解密引擎,和AES、OTFDEC一样,在L562系列中集成,L552系列中没有。所以这一集的动手环节我们也会基于搭载STM32L562的L5-Disco板子。


课程用到的板子,都可以在STM32官方天猫旗舰店购买。另外多说一句,PKA并非首次出现在STM32系列产品中,在STM32WB中也集成了PKA模块。



公钥加解密技术,可以解决在非安全网络中如何安全地交换信息的问题。


通信双方,发送消息的人,使用对方的公钥对消息加密。接收者使用自己的私钥对消息解密。考虑到非对称加解密所需的大量运算,它通常用于通信双方加密通道的对称秘钥的分发。基于这种方案,需要的是一个可信而集中的公钥仓库。确保你拿到的号称是“A的公钥”的这把钥匙 ,真正是A的,而不是B的,才能防止中间人对通信过程的攻击。


关于密码学的基本概念,可以参照我的另外一个《信息安全》视频课程,可以在AI电堂公众号和STM32中文官网上找到。



公钥加解密技术还可以用于数字签名。


数字签名是一个非常有用的技术,来保证数字资产,比如转账所需令牌的完整性、认证性,和不可抵赖性。


A要对自己的消息签名,需要先对该消息计算一下哈希值,然后使用自己的私钥对该哈希值执行签名操作,得到的结果就是A对该消息的数字签名。A把这段消息,连同该消息的数字签名一起发送给B。


B这个人如何验证收到的消息确实是A发过来,且没有在传输过程中被有意或者无意的篡改呢?他需要对收到的消息做同样的哈希操作,得到的值和使用A的公钥对A传过来的消息数字签名做了验签操作后得到结果做比较。二者相同,说明该消息确实是来自A,且消息未被篡改。


以上是PKA模块的常见应用领域,接下来再看看我们STM32L5和WB上面集成的这个PKA模块的一些参数。



在宏观层面,PKA支持非对称加解密标准运算,包括模幂运算、以及中国余数定理快速运算,ECC标量乘法,检查公钥点是否在给定ECC曲线上、ECDSA签名计算和验签计算。


微观,或者说算术和幂运算操作层面,PKA模块支持加法、减法、乘法、比较运算,以及模逆、模减运算。


这些操作的组合,可以实现很多公钥技术国际标准:RSA、ECC、ECDSA等。


在密钥长度方面,RSA支持3136位;ECC支持640位


PKA模块作为AHB从设备,直接挂在AHB总线上,它只支持32位字长度的读写操作。考虑到Trustzone使能下的安全应用背景,PKA是非TZ-aware的外设,它本身不能识别过来target到它的transaction上携带的安全信号,需要GTZC中的TZSC子模块来帮助识别和判断。



PKA模块硬件上由执行关键计算的PKA core,和专门给PKA core使用的PKA memory两部分组成。


由于PKA是AHB总线从设备,因此PKA core逻辑电路和PKA memory都是由AHB CLK来提供工作时钟。


用户只需要把数据放到PKA 内部专用memory里,然后通过PKA控制寄存器设置操作模式,最后置位START位即可。PKA硬件模块就开始无需CPU干预的进行计算,计算完毕,PROCENDF标志被硬件置位,用户就可以从PKA memory里读取运算结果了,并清除PROCENDF标志。


PKA硬件引擎计算过程中,软件随时可以通过复位PKA_CR控制寄存器的EN位域来放弃当前计算,那么PKA memory中的结果是不确定的内容。


AHB2RSTR复位寄存器可以控制PKA硬件模块的复位,复位信号释放后,经过894个时钟周期,PKA memory内容被清零。在这段时间内,用户如果企图置位PKA控制寄存器的EN位,是无效的。另外,从安全角度来考虑,当系统检测到tamper入侵事件,PKA RAM的内容也会被硬件清零。


按照刚才的描述,PKA模块的操作流程大概可以由6个步骤组成。使能PKA模块,往PKA memory里写入数据,配置PKA硬件引擎的工作模式,启动计算、等待计算完成标志,从PKA memory读取结果数据。


PKA模块的灵活之处就在于工作模式有很多种,包括宏观层面的,比如:RSA加解密,即模幂计算,设置mode=00;模幂计算,分使用私钥来计算,或者使用公钥来计算两种。


当使用私钥进行模幂运算,即做数字签名或者解密操作时,一般私钥都是很大的数,可以使用CRT来做加速,它会用到私钥的P、Q参数进行计算,对应mode=0x07。


在椭圆曲线ECC上的相关操作,PKA支持标量乘法及其对应的快速模式,mode分别是0x20和0x22。基于ECC做数字签名的ECDSA和对应ECDSA验签,mode分别是0x24和0x26。


除了这些宏观层面上支持的操作。用户还可以在微观层面使用PKA硬件引擎提供的算术加法、减法、乘法、比较;模加、模减、模逆,取模各自灵活的计算模式。



我们现在以PKA模块的模幂运算来体会如何使用PKA做RSA加解密。


运行RSA操作之前,我们需要准备好一对公钥、私钥对。公钥通常由(n,e)来表示,私钥是d。n是模,e和d分别是公钥指数、私钥指数。它们都是很大的整数。私钥也可以用p、q系列的参数来表示,常用于使用中国余数定理做模幂运算的加速。


公钥和私钥准备就绪,按照RSA原理,使用公钥(n,e)对消息M做加密,就是相对消息M进行编码然后转换成整数m,对证书m做模幂运算,即m的e次方,再对n取模,得到整数c,再把整数c转成字符C,得到消息M的密文C。使用私钥d对密文C解密,也是相同的运算过程:


现将密文字符C转成整数c,对整数c做模幂运算,c的d次方,再对n取模,得到整数m,然后将整数m转成消息字符M。如果私钥使用p, q形式表示的五元组,那么模幂计算,要分别使用p、q做模,dp,dp分别做指数来运算。


在CubeL5固件包的L562-DK板子上,有一个PKA的文件夹,下面选择ModularExponentiation例程。打开工程,在User group下有四个c文件,分别存放明文消息、密文消息、公钥和私钥。



使用特权

评论回复
沙发
powerantone|  楼主 | 2023-11-27 15:57 | 只看该作者

打开公钥文件看一下,里面包含模//modulus和公钥指数//public exponent。我们运行一个RSA2048计算,因此模的长度也是2048位,就是256个字节。公钥指数,通常我们可以选择一个较小的数,通常是65537,也经常使用2^16+1来表示。


再打开私钥文件看一下,同样的模,公钥指数,这些和公钥文件中一样。关键信息是私钥指数,同样也是2048位。


之前说了,如果想使用中国余数定理加速私钥的模幂运算,那么私钥可以用p,q系列的五元组来表示,在另外一个例子ModularExponentiationCRT中用这些参数的使用演示。



我们还是先来看标准RSA计算的例子,main.c中是对PKA HAL驱动的调用,也是用户执行PKA运算的逻辑。


由前后两部分组成,先是对明文加密,使用较小的公钥指数和2048位的模;然后对密文解密,使用2048位的私钥指数和相同的模。


加密过程在胶片的左面,解密过程在胶片的右面。这样并排一方,可以清晰地看到,RSA的加密、解密运算,是完全对称的。仅仅是把密钥参数从私钥换成公钥,把输入数据从明文换成密文。使用的HAL驱动和调用的顺序都完全一模一样。紫色方框部分是这种PKA硬件引擎的工作模式,都是mode=0x00,即:标准模幂运算。


我们来实际在板子上运行一下


>> 关掉优化,再编译


>> 检查板子选项字节配置,再下载


运行过程中,明显第二次用私钥计算的单步执行,可以感觉慢一点。我们加上计时代码,定量的看一下


添加计时相关代码:定义计时数组,初始化定时器,在想要考察的任务头、尾处添加时间戳记录。


我们准备对两端操作时间考察,一个是把操作数,即密钥、公钥,密文、明文,装载到PKA专用memory所需的时间。这个装载只能由CPU完成,不支持DMA。


另外一个是PKA硬件引擎执行模幂计算的时间,因此在PKA_Process() 函数里,置位START开始,到查询到操作完成标志置位结束。



运行起来,第一次PKA运行,停在memcmp这一句结束,来看timestamp数组,在运行过程中打了四个点,分别在关系的两个过程的一前一后,根据delta,可以大约得到这两个过程分别所耗的时钟周期。


我们再添加ICACHE使能,比较缺省状态下未使能ICACHE的情况下的运行测试结果。第一次运行结果是公钥参与的模幂计算,大概是135万个时钟周期,和STM32L5参考手册给出的表格,基本可以对的上。2048位RSA,公钥指数65536,通用用2^16+1表示,然后采用普通计算模式,而不是CRT快速计算方式。


表格里是大概122万个时钟周期。按照表格给出的理论值,计算出在以STM32L5最高主频110MHz的算力下,2048位公钥模幂运算,就是做加密或者验签,大约需要11ms左右。


继续运行,断点打在第二次memcmp结束的地方,这是使用2048位的私钥做模幂运算,按照表格8000多万个时钟周期,折算下来就是762ms。即RSA2048做解密或者签名,需要700多个ms。


《main.c》
#ifdef DWT_CYCCNT
uint32_t TimeStamp[4] = {0};
#endif

/* USER CODE BEGIN 1 */
#ifdef DWT_CYCCNT
  CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
    /* Reset cycle counter */
  DWT->CYCCNT = 0;
  DWT->CTRL = 0x1;
#endif
  /* USER CODE END 1 *

《stm32l5xx_hal_pka.c》
#ifdef DWT_CYCCNT
extern uint32_t TimeStamp[];
#endif

#ifdef DWT_CYCCNT
  TimeStamp[0] = DWT->CYCCNT;
#endif
  /* Set input parameter in PKA RAM */
  PKA_ModExp_Set(hpka, in);
#ifdef DWT_CYCCNT
  TimeStamp[1] = DWT->CYCCNT;
#endif


#ifdef DWT_CYCCNT
  TimeStamp[2] = DWT->CYCCNT;
#endif
    /* Start the computation */
    hpka->Instance->CR |= PKA_CR_START;

#ifdef DWT_CYCCNT
  TimeStamp[3] = DWT->CYCCNT;
#endif
    /* Check error */
    hpka->ErrorCode |= PKA_CheckError(hpka, mode);


STM32L5参考手册里的表格,列出的是不同模长度情况下,使用不同长度密钥做RSA模幂计算的时钟周期,它不是以时间为单位,不是太直观。因此这个胶片把主要参数使用情境下的耗时列了出来,更加直观。


我们CubeL5固件包里和RSA模幂运算相关的例子,一个是刚才的标准模式,在使用值为65537的常用公钥情况下,最快可以11ms完成加密或者说验签操作;而对应的私钥很长,对应的解密和签名操作就需要大概762ms。


如果大家运行另外一个CRT例程,把计时代码也加进去测试一下,可以体会到,使用相同2048位私钥做RSA模幂运算,CRT快速模式的耗时,可以节省至少2/3,大概213毫秒。



CubeL5固件包里RSA模幂运算都是使用的2048位模长度,如果应用需要3072位RSA计算,我们首先要产生对应的公钥、私钥对,然后调整PKA调用的HAL驱动参数。


很多PC端工具可以生成RSA公私钥对。我们以gitbash为例来演示。


启动gitbash,输入命令:openssl genrsa –out rsa_priv_3072.pem 3072,然后你可以在当前目录下看到生成的公钥和私钥文件,它们是经过编码后,使用文本编辑器打开,可以看到标准的BEGIN和END标志文本。我们需要提前公钥私钥的二进制数据,放到代码中参与运算。于是在命令行输入命令:openssl rsa -in rsa_priv_3072.pem  -text。就能看到模,公钥,私钥的二进制数据。

模和私钥指数,都是3072位的很大的大数,公钥指数还是常见的65537。把这两个大数据拷贝出来,去掉每个字节之间的【:】字符,每个数字字节前加上【0x】字符


关于RSA公私钥对的产生,小结一下。我们使用openssl中的genrsa命令,先生成3072位的私钥pem文件。可以继续使用rsa命令,由新生成的私钥文件计算出对应的公钥pem文件。


对两个公钥和私钥pem文件,继续使用rsa命令,得到对应的模、公钥指数、私钥指数二级制数据内容。经过矩阵化,作为数组,就可以被用到我们的工程中,作为参数喂给PKA硬件引擎,参与指定的模幂运算。






我们把新的密钥文件放到项目中,调整PKA模幂计算的输入参数,明文可以保持不变,甚至长度还是256字节、2048位没有问题。我们直接对明文加密,再对明文解密,得到的结果和明文数组比较。


在运行成功后,当然是比较结果一致,再添加计时代码,做一个耗时的参考。最后我们还是使用STM32L5参考手册里的数据值,转换成时间单位,得到一个感性的认识:使用RSA3072,加密和验签,大概需要24ms,而签名和解密,需要2.5s。



非对称加解密技术中,除了RSA之外,基于ECC椭圆曲线的数字签名和验签技术,也是运用非常广泛的算法。


在做ECC操作之前,通信双方协商出一条大家都能支持的曲线。PKA硬件引擎支持的曲线可以在STM32L5参考手册中查阅。


曲线确定了,它的相关参数就都确定了,包括模p,阶数n、曲线方程y2=x3+ax+b里面的协系数a和b,以及曲线的基点G。p和n的位数通常都一样,国际标准委员会发布的安全的ECC曲线中,有256位、320位、384位、512位、521位。协系数b、节点G的投影坐标值xG、yG,也都是很大的数,协系数a在由NIST发布的曲线上,通常是-3。


如何使用自己的私钥dA,对消息m做签名呢?这里私钥dA是一个整数。


先计算出消息的哈希值e,采用主流SHA2做哈希计算,根据模式不同,生成的哈希值有224、256、384和512位几种。


对生成的哈希值,取低几位,作为z。取低几位呢?位数就是曲线的阶数n,刚才说了有256,320,384,512位几种选择。


选择一个0到阶数n之间的随机数k,对基点G做k次点乘,后续是做各种大数的算术乘法、除法和取模。最后得到一对大数:r,s,作为使用私钥dA和消息m,在选定曲线上的签名。整个过程中,私钥dA和随机数k,都是需要保密的。


以上过程汇总,步骤4,5,6可以使用PKA做硬件加速。加速的方式有两种,一个是调用宏观API,即直接使用PKA支持的ECDSA这个工作模式,或者调用微观API的点乘,取模,模幂操作来组合完成。


我们打开STM32L5Cube固件包里DK板子下的PKA例子集合中的PKA_ECDSA_Sign。工程项目中有两个大家看起来比较陌生的文件:prime256v1.c,是NIST发布一的条安全椭圆曲线。里面列出了曲线的阶数、模、系数a、系数b、基点G,对应的x、y坐标值。SigGen.c,是从NIST-CAVP测试向量中选择的一个测试消息、选择的私钥d,随机数k,以及在NIST P-256曲线上做签名操作后的签名值。


PKA的HAL驱动封装出了对用户非常友好简便的接口,使用宏观API时,只要在输入参数中指定好两大部分内容,所用的曲线,和所用的私钥d、随机数k以及消息哈希值即可。


接下来,下载运行,直观体验一下。


和签名对应的操作是验签,ECDSA的验签原理:首先要确保对方的公钥点,在对应曲线上。这会用到PKA硬件引擎的另外一个工作模式,例程可以参考PKA例程集合目录下的“PKA_PointCheck”。对公钥点还要做另外两个核实,都可以使用PKA硬件引擎的“点乘”工作模式来完成。


验签方拿到了待验证的消息,消息的数字签名,可以使用PKA硬件引擎的“ECDSA 验签”来完成后续的大数计算。


我们打开STM32L5Cube固件包里DK板子下的PKA例子集合中的PKA_ECDSA_Verify。工程项目中的prime256v1.c文件和上一个例程一样,是NIST发布的一条安全椭圆曲线。里面列出了曲线的所有参数。SigVer.c,同上一个签名例子里的文件SigGen.c一样,是从NIST-CAVP测试向量中选择的一个测试样本。提供待测消息,其签名值,以及公钥点。


PKA的HAL驱动封装出了对用户非常友好简便的接口,只要在输入参数中指定好两大部分内容,所用的曲线,和所用的消息哈希值,公钥点即可。


使用特权

评论回复
板凳
powerantone|  楼主 | 2023-11-27 15:58 | 只看该作者

接下来,下载运行,直观体验一下。



我们把ECDSA签名和验签两个例子放在一起看一下,从在main.c里用户配置PKA引擎的工作输入参数和工作模式,以及调用HAL驱动来看。


在输入参数中,二者使用相同的曲线,签名操作还需要私钥d,随机数k,消息哈希值;而验签操作需要公钥点、消息的数字签名,和消息哈希值。


从前两个胶片,对ECDSA签名和验签的规范描述,两个操作不是对称的,从输入的参数也可以看出来,两个操作需要的输入参数不是完全相同。



使用同样的方法,在ECDSA签名和验签两个操作里,加上计时代码,可以粗略估算出对P256曲线做签名和验签,大概需要500多万和1000多万个CPU周期。


按照STM32L5参考手册给出的精确值,我们折算成L5按照110MHz主频的最大算力,那么就是需要47ms做签名,95ms最验签。


比较同等强度下,RSA3072的签名和验签,分别要使用2500ms,和24ms。由此可见,ECC做验签更快,RSA做签名更快。


最后再提一下PKA模块的中断和低功耗模式。


PKA模块可以有三种中断源:计算完成、PKA专有memory访问出错、PKA专有memory地址出错。三种事件都会触发PKA模块的唯一一条中断线给到NVIC控制器。



前面多次提过,往PKA memory里装载操作数的过程,只能由CPU完成,不支持DMA搬移。所以在前四个例程运行中,我们都有添加计时代码,去考察装载操作数过程所需的大概时间。



低功耗方面,PKA模块在stop模式就不工作了,在Run以下、Stop以上的三种低功耗模式,PKA模块在缺省状态下是不工作的,但是用户可以通过软件来使能。



关于STM32L5的PKA模块介绍,就到此结束。我们也完成了STM32L5的第二季全部课程。


如果你一直从第一季看到了这里,那么恭喜你已经对STM32L5有了非常全面的了解。从TZ架构,到芯片特有的安全特性都有了清晰和深入的认识以及体会。


谢谢大家的关注。对课程内容有什么建议和意见,欢迎大家在网站后台或者AI电堂后台给我留言,再次谢谢大家。


使用特权

评论回复
地板
童雨竹| | 2024-7-21 08:26 | 只看该作者

会使二极管导通

使用特权

评论回复
5
Wordsworth| | 2024-7-21 09:29 | 只看该作者

对于电力电路来说串联的电阻起阻尼作用

使用特权

评论回复
6
Clyde011| | 2024-7-21 10:32 | 只看该作者

甚至会造成模块电源的损坏

使用特权

评论回复
7
公羊子丹| | 2024-7-21 11:25 | 只看该作者

将ESD静电保护二极管并联于电路中

使用特权

评论回复
8
万图| | 2024-7-21 12:28 | 只看该作者

电阻阻值大小则需根据元器件可承受电流大小而决定

使用特权

评论回复
9
Uriah| | 2024-7-21 13:31 | 只看该作者

小型电子设备

使用特权

评论回复
10
帛灿灿| | 2024-7-21 15:27 | 只看该作者

电阻元件的电阻值大小一般与温度,材料,长度,还有横截面积有关

使用特权

评论回复
11
Bblythe| | 2024-7-21 16:30 | 只看该作者

灌封之前需要使用抽空机进行天然脱泡和真空脱泡预处理

使用特权

评论回复
12
周半梅| | 2024-7-21 18:26 | 只看该作者

当电压超过二极管的导通电压的时候

使用特权

评论回复
13
Pulitzer| | 2024-7-21 19:29 | 只看该作者

在低成本控制器内部有时候会没有钳位二极管

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

567

主题

2517

帖子

4

粉丝