无障碍 关怀版

为什么DCP硬件引擎做Hash校验偶尔会失败?

大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是 利用i.MXRT1xxx系列内部DCP引擎计算Hash值时需特别处理L1 D-Cache

关于i.MXRT1xxx系列内部通用数据协处理器DCP模块,痞子衡之前写过一篇文章 《SNVS Master Key仅在i.MXRT10xx Hab关闭时才能用于DCP加解密》 介绍了DCP基本功能和AES加解密使用注意事项,实际上DCP模块除了对AES加解密算法支持外,还支持经典的Hash算法(SHA-1/SHA-256/CRC32)。

痞子衡最近支持一个i.MXRT大客户,他们项目里使用了DCP做Hash运算,但会出现概率性Hash校验失败的情况(差不多运行50次,会失败1次),这是什么情况?

一、客户项目基本情况

先介绍下客户基本情况,他们项目使用的主芯片是i.MXRT1062,并且配置了外部串行Flash存储程序代码(XiP),以及外部SDRAM放置程序数据区(其实主要是做frameBuffer的,但也同时放置了.data段和STACK),项目基于的SDK版本是v2.6.2。

项目中主要调用了 \SDK_2.6.2_EVK-MIMXRT1060\middleware\mbedtls\library\sha256.c 中的 mbedtls_sha256 函数,这个函数其实是通过调用 \SDK_2.6.2_EVK-MIMXRT1060\middleware\mbedtls\port\ksdk\ksdk_mbedtls.c 里的一系列底层函数mbedtls_sha256_xx 来进一步实现的。

ksdk_mbedtls.c 文件是同时适用Kinetis/LPC/i.MXRT等系列MCU的,不同MCU上硬件引擎不同(比如有LTC/CAAM/CAU3/DCP/HashCrypt)。对于i.MXRT1xxx,硬件引擎就是DCP,这些 mbedtls_sha256_xx 函数主要调用了 SDK 标准驱动 fsl_dcp.c 里的如下函数:

status_tDCP_HASH_Init(DCP_Type *base, dcp_handle_t*handle, dcp_hash_ctx_t*ctx, dcp_hash_algo_talgo) ;

status_tDCP_HASH_Update(DCP_Type *base, dcp_hash_ctx_t*ctx, constuint8_t*input, size_tinputSize) ;

status_tDCP_HASH_Finish(DCP_Type *base, dcp_hash_ctx_t*ctx, uint8_t*output, size_t*outputSize) ;

二、概率性失败情况分析

既然是概率性失败的问题,那大概率和Cache处理有关了,我们需要检查下 fsl_dcp.c 驱动是否很好地处理了Cache。让我们打开 \SDK_2.6.2_EVK-MIMXRT1060\boards\evkmimxrt1060\driver_examples\dcp 例程先看一下,在 dcp.c 文件的 main 函数里可以看到明显的提醒。如果项目里用到了SDRAM,必须将DCache关掉,说明 dcp 驱动并不支持在DCache使能下运行。但显然这个客户项目用到了SDRAM,后来跟客户确认,他们DCache一直是使能的,这显然是有问题的。

intmain( void)

{

dcp_config_tdcpConfig;

/* Init hardware*/

BOARD_ConfigMPU;

BOARD_InitPins;

BOARD_BootClockRUN;

BOARD_InitDebugConsole;

/* Data cache must be temporarily disabled to be able to use sdram */

SCB_DisableDCache;

...

让我们再次回到SDK版本,在 恩智浦SDK下载主页 可以看到所有i.MXRT1060 SDK历史版本,v2.6.2是2019年7月发布的(这个版本里的dcp驱动版本是v2.1.1),是的,这个客户算是i.MXRT早期客户了。而现在最新的SDK版本已经是v2.9.3(dcp驱动已经升级到v2.1.6),时间快过去两年了,客户并没有实时更新SDK版本。

早期的 dcp 驱动没有处理DCache,所以其必须在 DCache 关掉的情况下才能正常工作。从v2.1.5开始增加了对 DCache 的处理,这样 dcp 驱动就可以在 DCache 使能的情况下正常工作了。

三、DCP驱动里是如何处理DCache的?

现在让我们在SDK标准驱动 fsl_dcp.c 中看一下它到底是怎么增加对DCache处理的。

3.1 DCP上下文buffer设置

使用 dcp 驱动的第一步是DCP模块初始化,即DCP_Init函数,这个函数会在DCP->CTRL寄存器里将模块全部的四通道都使能以及将上下文(Context)的缓存和通道自切换功能也都开启,其中关于上下文切换有一个重要的私有全局变量 s_dcpContextSwitchingBuffer,这个变量被放置到了NON-CACHE区域(驱动改进处一)。下述DCP->CONTEXT寄存器就是用来存储 s_dcpContextSwitchingBuffer 地址的。

AT_NONCACHEABLE_SECTION_INIT( staticdcp_context_ts_dcpContextSwitchingBuffer);

voidDCP_Init(DCP_Type *base, constdcp_config_t*config)

{

// 代码省略...

/* use context switching buffer */

base->CONTEXT = ( uint32_t)&s_dcpContextSwitchingBuffer;

}

3.2 DCP用户数据in/out buffer设置

DCP 模块初始化完成后,就是调用 dcp 驱动里的DCP_HASH函数进行Hash运算,这个函数参数里有两个用户Buffer,一个Input Buffer存放待计算的消息数据,另一个Output Buffer存放计算好的Hash值(SHA256是32bytes),这两个Buffer最好由用户处理放置在NON-CACHE区。

/* Input data for DCP like input and output should be handled properly

* when DCACHE is used (e.g. Clean&Invalidate, use non-cached memory)

*/

AT_NONCACHEABLE_SECTION( staticuint8_ts_outputSha256[ 32]);

status_tcalc_sha256( constuint8_t*messageBuf, uint32_tmessageLen)

{

size_toutLength = sizeof(s_outputSha256);

dcp_handle_tm_handle;

m_handle.channel = kDCP_Channel0;

m_handle.keySlot = kDCP_KeySlot0;

m_handle.swapConfig = kDCP_NoSwap;

memset(&s_outputSha256, 0, outLength);

returnDCP_HASH(DCP, &m_handle, kDCP_Sha256, messageBuf, messageLen, s_outputSha256, &outLength);

}

3.3 DCP_HASH相关代码中DCache处理

DCP_HASH函数运行过程中会一直用到一个非常关键的内部结构体 dcp_hash_ctx_internal_t,这个结构体大小为47 Words(包含128byte的待计算消息数据块blk、32bytes实时计算结果runningHash、及其他辅助变量成员)。

/*! internal dcp_hash context structure */

typedefstruct_ dcp_hash_ctx_internal

{

dcp_hash_block_tblk; /*!< memory buffer. only full blocks are written to DCP during hash updates */

size_tblksz; /*!< number of valid bytes in memory buffer */

dcp_hash_algo_talgo; /*!< selected algorithm from the set of supported algorithms */

dcp_hash_algo_state_tstate; /*!< finite machine state of the hash software process */

uint32_tfullMessageSize; /*!< track message size */

uint32_tctrl0; /*!< HASH_INIT and HASH_TERM flags */

uint32_trunningHash[ 9]; /*!< running hash. up to SHA-256 plus size, that is 36 bytes. */

dcp_handle_t*handle;

} dcp_hash_ctx_internal_t;

dcp 驱动直接定义了 dcp_hash_ctx_t 型局部变量hashCtx,hashCtx空间后续会被用作dcp_hash_ctx_internal_t。旧版本里DCP_HASH_CTX_SIZE值为58,新版本增加到64,这是为了后续L1DCACHE的LINE对齐(驱动改进处二)。

/*! @brief DCP HASH Context size. */

# defineDCP_HASH_CTX_SIZE 64

/*! @brief Storage type used to save hash context. */

typedefstruct_ dcp_hash_ctx_t

{

uint32_tx[DCP_HASH_CTX_SIZE];

} dcp_hash_ctx_t;

status_tDCP_HASH(DCP_Type *base, dcp_handle_t*handle, dcp_hash_algo_talgo, constuint8_t*input, size_tinputSize, uint8_t*output, size_t*outputSize)

{

dcp_hash_ctx_thashCtx = { 0};

status_tstatus;

status = DCP_HASH_Init(base, handle, &hashCtx, algo);

status = DCP_HASH_Update(base, &hashCtx, input, inputSize);

status = DCP_HASH_Finish(base, &hashCtx, output, outputSize);

// ...

}

status_tDCP_HASH_Init/Update/Finish(..., dcp_hash_ctx_t*ctx,...)

{

dcp_hash_ctx_internal_t*ctxInternal;

/* Align structure on DCACHE line*/

# ifdefined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) && defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U)

ctxInternal = ( dcp_hash_ctx_internal_t*)( uint32_t)(( uint8_t*)ctx + FSL_FEATURE_L1DCACHE_LINESIZE_BYTE);

# else

ctxInternal = ( dcp_hash_ctx_internal_t*)( uint32_t)ctx;

# endif

// 代码省略...

}

DCP_HASH函数中启动DCP引擎去计算消息块数据前,都会调用 DCACHE_InvalidateByRange 函数对 ctxInternal 所占空间做清理(驱动改进处三)。启动DCP引擎工作一次的函数是dcp_hash_update,这个函数会利用 dcp_work_packet_t 型结构体变量,对于这个结构,代码中也同样做了L1DCACHE对齐处理(驱动改进处四):

/*! @brief DCP's work packet. */

typedefstruct_ dcp_work_packet

{

uint32_tnextCmdAddress;

uint32_tcontrol0;

uint32_tcontrol1;

uint32_tsourceBufferAddress;

uint32_tdestinationBufferAddress;

uint32_tbufferSize;

uint32_tpayloadPointer;

uint32_tstatus;

} dcp_work_packet_t;

# ifdefined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) && defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U)

staticinlineuint32_t* DCP_FindCacheLine( uint8_t*dcpWorkExt)

{

while( 0U!= (( uint32_t)dcpWorkExt & (( uint32_t)FSL_FEATURE_L1DCACHE_LINESIZE_BYTE - 1U)))

{

dcpWorkExt++;

}

return( uint32_t*)( uint32_t)dcpWorkExt;

}

# endif

staticstatus_tdcp_hash_update(DCP_Type *base, dcp_hash_ctx_internal_t*ctxInternal, constuint8_t*msg, size_tsize)

{

status_tcompletionStatus = kStatus_Fail;

/* Use extended DCACHE line size aligned structure */

# ifdefined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) && defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U)

dcp_work_packet_t*dcpWork;

uint8_tdcpWorkExt[ sizeof( dcp_work_packet_t) + FSL_FEATURE_L1DCACHE_LINESIZE_BYTE] = { 0U};

dcpWork = ( dcp_work_packet_t*)( uint32_t)DCP_FindCacheLine(dcpWorkExt);

# else

dcp_work_packet_tdcpWorkPacket = { 0};

dcp_work_packet_t*dcpWork = &dcpWorkPacket;

# endif

do

{

completionStatus = dcp_hash_update_non_blocking(base, ctxInternal, dcpWork, msg, size);

} while(completionStatus == ( int32_t)kStatus_DCP_Again);

completionStatus = DCP_WaitForChannelComplete(base, ctxInternal->handle);

ctxInternal->ctrl0 = 0;

return(completionStatus);

}

至此,利用i.MXRT1xxx系列内部DCP引擎计算Hash值时需特别处理L1 D-Cache痞子衡便介绍完毕了,掌声在哪里~~~

1. 为什么说Arm-2D是小资源单片机的GUI人权卡!

2.有了这些小技巧,我的代码可以起飞了~

3.QP是什么,为什么在国内不为我们所熟悉?

4.突发!又一MCU大厂暂停接单!

5.对国产嵌入式操作系统,你了解多少?

6.GitHub上与嵌入式相关的高星开源项目~

免责声明:本文系网络转载,版权归原作者所有。如涉及作品版权问题,请与我们联系,我们将根据您提供的版权证明材料确认版权并支付稿酬或者删除内容。 返回搜狐,查看更多

责任编辑:

平台声明:该文观点仅代表作者本人,搜狐号系信息发布平台,搜狐仅提供信息存储空间服务。
阅读 ()

玻璃钢生产厂家郑州专业玻璃钢人物雕塑定做价格安庆大型户外玻璃钢雕塑厂家武汉玻璃钢雕塑模具价格惠州玻璃钢不锈钢雕塑做玻璃钢雕塑设计商场顾客休息区域的美陈布置商场装饰玻璃钢卡通雕塑代理价格龙亭玻璃钢雕塑长方形玻璃钢花盆价格商场天井美陈图片玻璃钢花盆弊端长沙玻璃钢雕塑设计厂家哪家好营口玻璃钢雕塑公司郑州人物玻璃钢彩绘雕塑设计福建公园玻璃钢雕塑价位长沙欧式玻璃钢雕塑供应商商场顾客休息区域的美陈布置商场广场美陈节日布置江门玻璃钢雕塑厂家供应玻璃钢狮子座雕塑山东玻璃钢小熊雕塑宜春玻璃钢雕塑订做价格江西景观玻璃钢雕塑销售电话雕塑玻璃钢型号天虎玻璃钢雕塑雕刻公司西宁仿真人物玻璃钢雕塑哪家好伊犁气球商场美陈装饰费用情况大型玻璃钢雕塑哪家比较好广东园林景观玻璃钢雕塑艺术摆件金华玻璃钢雕塑市场香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化