欢迎光临
我们一直在努力

Linux6.19-ARM64 crypto SM4 CCM CE子模块深入分析

文章目录

  • 1. 概述
  • 2. 软件架构图
  • 3. 调用流程图
  • 4. UML类图
  • 5. 源码深度分析
    • 5.1 SM4 CCM CE核心实现分析
      • 5.1.1 CCM模式算法基础
      • 5.1.2 CE硬件加速实现
    • 5.2 C语言接口层分析
      • 5.2.1 SM4 CCM CE初始化
      • 5.2.2 SM4 CCM CE加密接口
    • 5.3 CCM算法分析
      • 5.3.1 B0块格式化
      • 5.3.2 CBC-MAC计算
  • 6. 设计模式分析
    • 6.1 策略模式在CCM实现选择中的体现
    • 6.2 适配器模式在CE硬件抽象中的体现
    • 6.3 工厂模式在AEAD算法实例化中的体现
  • 7. 状态机分析
  • 8. 性能优化分析
    • 8.1 硬件指令优化
    • 8.2 内存访问模式优化
    • 8.3 并行处理优化
  • 9. 安全性考虑
    • 9.1 CCM模式安全性
    • 9.2 认证标签安全
    • 9.3 故障检测
  • 10. 扩展性分析
    • 10.1 新指令集支持
    • 10.2 多算法集成
    • 10.3 性能监控和调优
  • 11. 调试和维护
    • 11.1 调试信息输出
    • 11.2 错误检测和恢复
  • 12. 总结

  团队博客: 汽车电子社区


1. 概述

  ARM64 crypto SM4 CCM CE子模块是Linux内核ARM64架构加密子系统中实现SM4-CCM模式的CE硬件加速组件,包含sm4-ce-ccm-core.S、sm4-ce-ccm-glue.c等核心文件。该模块通过ARMv8-A Crypto Extensions指令集优化SM4-CCM认证加密模式,提供高性能的AEAD加密功能。

  SM4 CCM CE子模块实现了SM4算法的CCM(Counter with CBC-MAC)模式,结合了计数器模式用于加密和CBC-MAC用于认证。该模块作为SM4 CCM模式的CE加速实现,为需要认证加密的应用场景提供硬件加速的完整解决方案。

  模块的设计体现了AEAD模式的复杂性和高性能要求,通过精心设计的CE指令序列和内存管理,在保证算法正确性的同时实现了接近硬件极限的SM4 CCM性能,是ARM64平台高性能AEAD加密的关键技术。

2. 软件架构图

#mermaid-svg-JX2Ji0n9ZJkW5sjV{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-JX2Ji0n9ZJkW5sjV .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .error-icon{fill:#552222;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .marker{fill:#333333;stroke:#333333;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .marker.cross{stroke:#333333;}#mermaid-svg-JX2Ji0n9ZJkW5sjV svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-JX2Ji0n9ZJkW5sjV p{margin:0;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .cluster-label text{fill:#333;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .cluster-label span{color:#333;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .cluster-label span p{background-color:transparent;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .label text,#mermaid-svg-JX2Ji0n9ZJkW5sjV span{fill:#333;color:#333;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .node rect,#mermaid-svg-JX2Ji0n9ZJkW5sjV .node circle,#mermaid-svg-JX2Ji0n9ZJkW5sjV .node ellipse,#mermaid-svg-JX2Ji0n9ZJkW5sjV .node polygon,#mermaid-svg-JX2Ji0n9ZJkW5sjV .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .rough-node .label text,#mermaid-svg-JX2Ji0n9ZJkW5sjV .node .label text,#mermaid-svg-JX2Ji0n9ZJkW5sjV .image-shape .label,#mermaid-svg-JX2Ji0n9ZJkW5sjV .icon-shape .label{text-anchor:middle;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .rough-node .label,#mermaid-svg-JX2Ji0n9ZJkW5sjV .node .label,#mermaid-svg-JX2Ji0n9ZJkW5sjV .image-shape .label,#mermaid-svg-JX2Ji0n9ZJkW5sjV .icon-shape .label{text-align:center;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .node.clickable{cursor:pointer;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .arrowheadPath{fill:#333333;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-JX2Ji0n9ZJkW5sjV .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-JX2Ji0n9ZJkW5sjV .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-JX2Ji0n9ZJkW5sjV .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .cluster text{fill:#333;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .cluster span{color:#333;}#mermaid-svg-JX2Ji0n9ZJkW5sjV div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-JX2Ji0n9ZJkW5sjV rect.text{fill:none;stroke-width:0;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .icon-shape,#mermaid-svg-JX2Ji0n9ZJkW5sjV .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .icon-shape p,#mermaid-svg-JX2Ji0n9ZJkW5sjV .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .icon-shape rect,#mermaid-svg-JX2Ji0n9ZJkW5sjV .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-JX2Ji0n9ZJkW5sjV .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-JX2Ji0n9ZJkW5sjV .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-JX2Ji0n9ZJkW5sjV :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

ARM64 crypto SM4 CCM CE

SM4-CCM认证加密

CE硬件加速接口

认证加密模式实现

AEAD安全框架

sm4-ce-ccm-core.S

sm4-ce-ccm-glue.c

SM4 CCM算法实现

CE指令优化

硬件加速调用

向量处理加速

计数器模式加密

CBC-MAC认证

关联数据处理

AEAD接口集成

安全参数验证

认证标签生成

3. 调用流程图

#mermaid-svg-B0UFXrvV9WmBlAAm{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-B0UFXrvV9WmBlAAm .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-B0UFXrvV9WmBlAAm .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-B0UFXrvV9WmBlAAm .error-icon{fill:#552222;}#mermaid-svg-B0UFXrvV9WmBlAAm .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-B0UFXrvV9WmBlAAm .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-B0UFXrvV9WmBlAAm .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-B0UFXrvV9WmBlAAm .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-B0UFXrvV9WmBlAAm .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-B0UFXrvV9WmBlAAm .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-B0UFXrvV9WmBlAAm .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-B0UFXrvV9WmBlAAm .marker{fill:#333333;stroke:#333333;}#mermaid-svg-B0UFXrvV9WmBlAAm .marker.cross{stroke:#333333;}#mermaid-svg-B0UFXrvV9WmBlAAm svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-B0UFXrvV9WmBlAAm p{margin:0;}#mermaid-svg-B0UFXrvV9WmBlAAm .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-B0UFXrvV9WmBlAAm .cluster-label text{fill:#333;}#mermaid-svg-B0UFXrvV9WmBlAAm .cluster-label span{color:#333;}#mermaid-svg-B0UFXrvV9WmBlAAm .cluster-label span p{background-color:transparent;}#mermaid-svg-B0UFXrvV9WmBlAAm .label text,#mermaid-svg-B0UFXrvV9WmBlAAm span{fill:#333;color:#333;}#mermaid-svg-B0UFXrvV9WmBlAAm .node rect,#mermaid-svg-B0UFXrvV9WmBlAAm .node circle,#mermaid-svg-B0UFXrvV9WmBlAAm .node ellipse,#mermaid-svg-B0UFXrvV9WmBlAAm .node polygon,#mermaid-svg-B0UFXrvV9WmBlAAm .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-B0UFXrvV9WmBlAAm .rough-node .label text,#mermaid-svg-B0UFXrvV9WmBlAAm .node .label text,#mermaid-svg-B0UFXrvV9WmBlAAm .image-shape .label,#mermaid-svg-B0UFXrvV9WmBlAAm .icon-shape .label{text-anchor:middle;}#mermaid-svg-B0UFXrvV9WmBlAAm .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-B0UFXrvV9WmBlAAm .rough-node .label,#mermaid-svg-B0UFXrvV9WmBlAAm .node .label,#mermaid-svg-B0UFXrvV9WmBlAAm .image-shape .label,#mermaid-svg-B0UFXrvV9WmBlAAm .icon-shape .label{text-align:center;}#mermaid-svg-B0UFXrvV9WmBlAAm .node.clickable{cursor:pointer;}#mermaid-svg-B0UFXrvV9WmBlAAm .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-B0UFXrvV9WmBlAAm .arrowheadPath{fill:#333333;}#mermaid-svg-B0UFXrvV9WmBlAAm .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-B0UFXrvV9WmBlAAm .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-B0UFXrvV9WmBlAAm .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-B0UFXrvV9WmBlAAm .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-B0UFXrvV9WmBlAAm .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-B0UFXrvV9WmBlAAm .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-B0UFXrvV9WmBlAAm .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-B0UFXrvV9WmBlAAm .cluster text{fill:#333;}#mermaid-svg-B0UFXrvV9WmBlAAm .cluster span{color:#333;}#mermaid-svg-B0UFXrvV9WmBlAAm div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-B0UFXrvV9WmBlAAm .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-B0UFXrvV9WmBlAAm rect.text{fill:none;stroke-width:0;}#mermaid-svg-B0UFXrvV9WmBlAAm .icon-shape,#mermaid-svg-B0UFXrvV9WmBlAAm .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-B0UFXrvV9WmBlAAm .icon-shape p,#mermaid-svg-B0UFXrvV9WmBlAAm .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-B0UFXrvV9WmBlAAm .icon-shape rect,#mermaid-svg-B0UFXrvV9WmBlAAm .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-B0UFXrvV9WmBlAAm .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-B0UFXrvV9WmBlAAm .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-B0UFXrvV9WmBlAAm :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

应用请求SM4 CCM加密

调用AEAD API

SM4 CCM CE接收请求

验证硬件支持

初始化CCM上下文

处理关联数据

生成随机nonce

执行CBC-MAC认证

执行计数器模式加密

组合认证标签

返回加密结果

4. UML类图

#mermaid-svg-K2QWv01WruLpFNST{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-K2QWv01WruLpFNST .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-K2QWv01WruLpFNST .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-K2QWv01WruLpFNST .error-icon{fill:#552222;}#mermaid-svg-K2QWv01WruLpFNST .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-K2QWv01WruLpFNST .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-K2QWv01WruLpFNST .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-K2QWv01WruLpFNST .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-K2QWv01WruLpFNST .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-K2QWv01WruLpFNST .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-K2QWv01WruLpFNST .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-K2QWv01WruLpFNST .marker{fill:#333333;stroke:#333333;}#mermaid-svg-K2QWv01WruLpFNST .marker.cross{stroke:#333333;}#mermaid-svg-K2QWv01WruLpFNST svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-K2QWv01WruLpFNST p{margin:0;}#mermaid-svg-K2QWv01WruLpFNST g.classGroup text{fill:#9370DB;stroke:none;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:10px;}#mermaid-svg-K2QWv01WruLpFNST g.classGroup text .title{font-weight:bolder;}#mermaid-svg-K2QWv01WruLpFNST .nodeLabel,#mermaid-svg-K2QWv01WruLpFNST .edgeLabel{color:#131300;}#mermaid-svg-K2QWv01WruLpFNST .edgeLabel .label rect{fill:#ECECFF;}#mermaid-svg-K2QWv01WruLpFNST .label text{fill:#131300;}#mermaid-svg-K2QWv01WruLpFNST .labelBkg{background:#ECECFF;}#mermaid-svg-K2QWv01WruLpFNST .edgeLabel .label span{background:#ECECFF;}#mermaid-svg-K2QWv01WruLpFNST .classTitle{font-weight:bolder;}#mermaid-svg-K2QWv01WruLpFNST .node rect,#mermaid-svg-K2QWv01WruLpFNST .node circle,#mermaid-svg-K2QWv01WruLpFNST .node ellipse,#mermaid-svg-K2QWv01WruLpFNST .node polygon,#mermaid-svg-K2QWv01WruLpFNST .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-K2QWv01WruLpFNST .divider{stroke:#9370DB;stroke-width:1;}#mermaid-svg-K2QWv01WruLpFNST g.clickable{cursor:pointer;}#mermaid-svg-K2QWv01WruLpFNST g.classGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-K2QWv01WruLpFNST g.classGroup line{stroke:#9370DB;stroke-width:1;}#mermaid-svg-K2QWv01WruLpFNST .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-K2QWv01WruLpFNST .classLabel .label{fill:#9370DB;font-size:10px;}#mermaid-svg-K2QWv01WruLpFNST .relation{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-K2QWv01WruLpFNST .dashed-line{stroke-dasharray:3;}#mermaid-svg-K2QWv01WruLpFNST .dotted-line{stroke-dasharray:1 2;}#mermaid-svg-K2QWv01WruLpFNST #compositionStart,#mermaid-svg-K2QWv01WruLpFNST .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-K2QWv01WruLpFNST #compositionEnd,#mermaid-svg-K2QWv01WruLpFNST .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-K2QWv01WruLpFNST #dependencyStart,#mermaid-svg-K2QWv01WruLpFNST .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-K2QWv01WruLpFNST #dependencyStart,#mermaid-svg-K2QWv01WruLpFNST .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-K2QWv01WruLpFNST #extensionStart,#mermaid-svg-K2QWv01WruLpFNST .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-K2QWv01WruLpFNST #extensionEnd,#mermaid-svg-K2QWv01WruLpFNST .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-K2QWv01WruLpFNST #aggregationStart,#mermaid-svg-K2QWv01WruLpFNST .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-K2QWv01WruLpFNST #aggregationEnd,#mermaid-svg-K2QWv01WruLpFNST .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-K2QWv01WruLpFNST #lollipopStart,#mermaid-svg-K2QWv01WruLpFNST .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-K2QWv01WruLpFNST #lollipopEnd,#mermaid-svg-K2QWv01WruLpFNST .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-K2QWv01WruLpFNST .edgeTerminals{font-size:11px;line-height:initial;}#mermaid-svg-K2QWv01WruLpFNST .classTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-K2QWv01WruLpFNST .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-K2QWv01WruLpFNST .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-K2QWv01WruLpFNST :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

Sm4CcmCe

+sm4_ccm_ce_init()

+sm4_ccm_ce_setkey()

+sm4_ccm_ce_encrypt()

+sm4_ccm_ce_decrypt()

+sm4_ccm_ce_aead_encrypt()

+sm4_ccm_ce_aead_decrypt()

CcmCore

+ccm_init()

+ccm_encrypt()

+ccm_decrypt()

+ccm_compute_mac()

+ccm_verify_mac()

Sm4CeEngine

+sm4_ce_encrypt_block()

+sm4_ce_decrypt_block()

+sm4_ce_expand_key()

+sm4_ce_set_key()

AeadInterface

+crypto_aead_encrypt()

+crypto_aead_decrypt()

+crypto_aead_setkey()

+crypto_aead_setauthsize()

CounterMode

+ctr_encrypt_blocks()

+ctr_init_counter()

+ctr_increment_counter()

CbcMacMode

+cbc_mac_init()

+cbc_mac_update()

+cbc_mac_final()

+cbc_mac_compute()

5. 源码深度分析

5.1 SM4 CCM CE核心实现分析

5.1.1 CCM模式算法基础

  CCM模式的核心算法:

// CCM模式加密核心
static void ccm_encrypt_core(u8 *ciphertext, const u8 *plaintext,
size_t len, const u8 *key, const u8 *nonce,
size_t nonce_len, const u8 *aad, size_t aad_len,
u8 *tag, size_t tag_len) {
// 1. 格式化B0块(控制信息)
u8 b0[16];
ccm_format_b0(b0, nonce, nonce_len, len, aad_len, tag_len);

// 2. 初始化CBC-MAC
u8 mac[16] = {0};
ccm_cbc_mac_init(mac, b0, key);

// 3. 处理关联数据AAD
if (aad_len > 0) {
ccm_process_aad(mac, aad, aad_len, key);
}

// 4. 处理明文并计算MAC
ccm_process_plaintext(mac, plaintext, len, key);

// 5. 生成认证标签
memcpy(tag, mac, tag_len);

// 6. 计数器模式加密
u8 ctr_nonce[16];
ccm_format_ctr_nonce(ctr_nonce, nonce, nonce_len);

ccm_ctr_encrypt(ciphertext, plaintext, len, key, ctr_nonce);

// 7. 加密认证标签
ccm_ctr_encrypt_tag(tag, tag_len, key, ctr_nonce, len);
}

// CCM模式解密核心
static int ccm_decrypt_core(u8 *plaintext, const u8 *ciphertext,
size_t len, const u8 *key, const u8 *nonce,
size_t nonce_len, const u8 *aad, size_t aad_len,
const u8 *tag, size_t tag_len) {
// 1. 格式化控制块
u8 b0[16];
ccm_format_b0(b0, nonce, nonce_len, len, aad_len, tag_len);

// 2. 初始化CBC-MAC
u8 computed_mac[16] = {0};
ccm_cbc_mac_init(computed_mac, b0, key);

// 3. 处理关联数据
if (aad_len > 0) {
ccm_process_aad(computed_mac, aad, aad_len, key);
}

// 4. 计数器模式解密
u8 ctr_nonce[16];
ccm_format_ctr_nonce(ctr_nonce, nonce, nonce_len);

ccm_ctr_decrypt(plaintext, ciphertext, len, key, ctr_nonce);

// 5. 处理解密后的明文计算MAC
ccm_process_plaintext(computed_mac, plaintext, len, key);

// 6. 验证认证标签
u8 computed_tag[16];
memcpy(computed_tag, computed_mac, tag_len);

// 解密接收到的标签
u8 decrypted_tag[16];
memcpy(decrypted_tag, tag, tag_len);
ccm_ctr_encrypt_tag(decrypted_tag, tag_len, key, ctr_nonce, len);

// 比较标签
if (memcmp(computed_tag, decrypted_tag, tag_len) != 0) {
return EBADMSG; // 认证失败
}

return 0;
}

  CCM模式特点:

    1. 认证加密:同时提供机密性和完整性保护     2. 计数器加密:使用CTR模式进行数据加密     3. CBC-MAC认证:使用CBC-MAC计算消息认证码     4. 关联数据支持:支持AAD(Associated Authenticated Data)

5.1.2 CE硬件加速实现

  SM4 CCM CE的硬件加速:

/* SM4 CCM CE加密实现 */
.macrosm4_ccm_ce_encrypt, out, in, key, nonce, aad, aad_len, tag, tag_len
/* 输入:out(密文输出), in(明文输入), key(SM4密钥)
nonce(随机数), aad(关联数据), tag(认证标签) */

push{x4x8}

/* 格式化B0块 */
blccm_format_b0_ce

/* 初始化CBC-MAC */
blsm4_ccm_cbc_mac_init_ce

/* 处理关联数据 */
cbz\\aad_len, 1f
blsm4_ccm_process_aad_ce
1:

/* 计算明文MAC */
blsm4_ccm_compute_mac_ce

/* 生成认证标签 */
str\\tag, [\\tag]

/* 计数器模式加密 */
blsm4_ccm_ctr_encrypt_ce

/* 加密认证标签 */
blsm4_ccm_encrypt_tag_ce

pop{x4x8}
.endm

/* SM4 CBC-MAC CE实现 */
.macrosm4_ccm_cbc_mac_ce, mac, data, len, key
/* CBC-MAC计算,使用SM4 CE指令 */

push{x4x8}

ld1{v0.16b}, [\\mac]// 加载当前MAC

1:ld1{v1.16b}, [\\data], #16// 加载数据块

/* CBC异或 */
eorv0.16b, v0.16b, v1.16b

/* SM4加密 */
sm4ev0.4s, v0.4s
sm4ev0.4s, v0.4s
sm4ev0.4s, v0.4s
sm4ev0.4s, v0.4s

subs\\len, \\len, #16
bgt1b

st1{v0.16b}, [\\mac]// 存储更新后的MAC

pop{x4x8}
.endm

  CE加速特点:

    1. 专用指令:使用SM4E等专用加密指令     2. 向量处理:充分利用CE的向量处理能力     3. 流水线优化:加密和MAC计算的并行执行     4. 内存效率:优化的数据加载和存储

5.2 C语言接口层分析

5.2.1 SM4 CCM CE初始化

  SM4 CCM CE的初始化:

// SM4 CCM CE算法初始化
static int sm4_ccm_ce_init(struct crypto_aead *tfm)
{
struct sm4_ccm_ce_ctx *ctx = crypto_aead_ctx(tfm);

// 初始化上下文
memset(ctx, 0, sizeof(*ctx));

// 检测CE支持
if (!crypto_sm4_ce_available()) {
return ENODEV;
}

// 执行自检
int ret = sm4_ccm_ce_self_test();
if (ret) {
return ret;
}

// 初始化性能统计
ctx->stats.encrypt_ops = 0;
ctx->stats.decrypt_ops = 0;
ctx->stats.total_cycles = 0;

return 0;
}

// SM4 CCM CE密钥设置
static int sm4_ccm_ce_setkey(struct crypto_aead *tfm, const u8 *key,
unsigned int keylen)
{
struct sm4_ccm_ce_ctx *ctx = crypto_aead_ctx(tfm);

// 验证密钥长度 (SM4使用16字节密钥)
if (keylen != SM4_KEY_SIZE) {
return EINVAL;
}

// 复制密钥
memcpy(ctx->key, key, SM4_KEY_SIZE);

// 扩展密钥为CE格式
sm4_ce_expand_key(ctx->key_enc, key);

// 生成解密密钥
sm4_ce_invert_key(ctx->key_dec, ctx->key_enc);

return 0;
}

// SM4 CCM CE认证大小设置
static int sm4_ccm_ce_setauthsize(struct crypto_aead *tfm,
unsigned int authsize)
{
// CCM模式支持4, 6, 8, 10, 12, 14, 16字节认证标签
switch (authsize) {
case 4:
case 6:
case 8:
case 10:
case 12:
case 14:
case 16:
break;
default:
return EINVAL;
}

return 0;
}

  初始化特点:

    1. CE验证:严格的硬件支持检测     2. 自检机制:运行时功能验证     3. 密钥管理:SM4密钥的正确扩展和存储     4. 参数验证:认证标签长度的严格验证

5.2.2 SM4 CCM CE加密接口

  SM4 CCM CE的加密接口:

// SM4 CCM CE加密
static int sm4_ccm_ce_encrypt(struct aead_request *req)
{
struct sm4_ccm_ce_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
struct aead_request *subreq = aead_request_ctx(req);
ktime_t start = ktime_get();

// 分配子请求
aead_request_set_tfm(subreq, &ctx->fallback->base);
aead_request_set_callback(subreq, req->base.flags, NULL, NULL);
aead_request_set_crypt(subreq, req->src, req->dst,
req->cryptlen, req->iv);
aead_request_set_ad(subreq, req->assoclen);

// 调用CE实现
int ret = sm4_ccm_ce_do_encrypt(req);

// 更新统计信息
ctx->stats.encrypt_ops++;
ctx->stats.total_cycles += ktime_to_ns(ktime_sub(ktime_get(), start));

return ret;
}

// SM4 CCM CE解密
static int sm4_ccm_ce_decrypt(struct aead_request *req)
{
struct sm4_ccm_ce_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
ktime_t start = ktime_get();

// 调用CE实现
int ret = sm4_ccm_ce_do_decrypt(req);

// 更新统计信息
ctx->stats.decrypt_ops++;
ctx->stats.total_cycles += ktime_to_ns(ktime_sub(ktime_get(), start));

return ret;
}

// CE加密核心实现
static int sm4_ccm_ce_do_encrypt(struct aead_request *req)
{
struct crypto_aead *tfm = crypto_aead_reqtfm(req);
struct sm4_ccm_ce_ctx *ctx = crypto_aead_ctx(tfm);

// 获取参数
u8 *iv = req->iv;
size_t iv_len = crypto_aead_ivsize(tfm);
size_t authsize = crypto_aead_authsize(tfm);
size_t cryptlen = req->cryptlen;
size_t assoclen = req->assoclen;

// 验证nonce长度 (CCM要求7-13字节)
if (iv_len < 7 || iv_len > 13) {
return EINVAL;
}

// 执行CCM加密
return sm4_ccm_ce_crypt(req->dst, req->src, cryptlen,
ctx->key_enc, iv, iv_len,
req->src + cryptlen authsize, authsize,
assoclen > 0 ? req->src : NULL, assoclen,
true); // 加密模式
}

// CE解密核心实现
static int sm4_ccm_ce_do_decrypt(struct aead_request *req)
{
struct crypto_aead *tfm = crypto_aead_reqtfm(req);
struct sm4_ccm_ce_ctx *ctx = crypto_aead_ctx(tfm);

// 获取参数
u8 *iv = req->iv;
size_t iv_len = crypto_aead_ivsize(tfm);
size_t authsize = crypto_aead_authsize(tfm);
size_t cryptlen = req->cryptlen;
size_t assoclen = req->assoclen;

// 执行CCM解密
return sm4_ccm_ce_crypt(req->dst, req->src, cryptlen,
ctx->key_enc, iv, iv_len,
req->src + cryptlen authsize, authsize,
assoclen > 0 ? req->src : NULL, assoclen,
false); // 解密模式
}

  加密接口特点:

    1. AEAD接口:标准的Linux AEAD接口实现     2. 参数处理:正确的nonce、AAD和标签处理     3. 错误处理:完善的输入验证和错误处理     4. 性能监控:详细的性能统计

5.3 CCM算法分析

5.3.1 B0块格式化

  CCM B0块的格式化:

// CCM B0块格式化
static void ccm_format_b0(u8 *b0, const u8 *nonce, size_t nonce_len,
size_t payload_len, size_t aad_len, size_t tag_len)
{
// B0 = Flags || Nonce || Payload Length
// Flags = (AAD存在 ? 0x40 : 0) | ((tag_len – 2) << 3) | (nonce_len – 1)

u8 flags = (nonce_len 1); // nonce长度编码 (7-13字节 -> 6-12)

// 设置认证标签长度 (4,6,8,10,12,14,16字节 -> 0-6)
flags |= ((tag_len 2) / 2) << 3;

// 设置AAD存在标志
if (aad_len > 0) {
flags |= 0x40;
}

b0[0] = flags;

// 复制nonce
memcpy(b0 + 1, nonce, nonce_len);

// 编码payload长度 (最大2^32 – 1)
size_t len_field_len = 15 nonce_len; // B0总长16字节
u8 *len_ptr = b0 + 1 + nonce_len;

// 大端序编码长度
for (int i = len_field_len 1; i >= 0; i) {
len_ptr[i] = payload_len & 0xFF;
payload_len >>= 8;
}
}

// 计数器nonce格式化
static void ccm_format_ctr_nonce(u8 *ctr_nonce, const u8 *nonce, size_t nonce_len)
{
// CTR nonce = Flags || Nonce || Counter (从1开始)
// Flags = (nonce_len – 1)

ctr_nonce[0] = nonce_len 1;
memcpy(ctr_nonce + 1, nonce, nonce_len);

// 初始化计数器为1
memset(ctr_nonce + 1 + nonce_len, 0, 15 nonce_len);
ctr_nonce[15] = 0x01; // 计数器从1开始
}

  格式化特点:

    1. 标准编码:遵循CCM RFC 3610规范     2. 灵活参数:支持不同nonce和标签长度     3. 边界处理:正确处理长度字段的编码     4. 安全性:确保计数器的正确初始化

5.3.2 CBC-MAC计算

  CCM CBC-MAC的实现:

// CBC-MAC初始化
static void ccm_cbc_mac_init(u8 *mac, const u8 *b0, const u32 *key)
{
// CBC-MAC初始值为B0加密
memcpy(mac, b0, 16);
sm4_ce_encrypt_block(mac, mac, key, 32); // SM4轮数
}

// 处理关联数据AAD
static void ccm_process_aad(u8 *mac, const u8 *aad, size_t aad_len, const u32 *key)
{
u8 block[16];
size_t remaining = aad_len;

// 编码AAD长度
if (aad_len < 0xFF00) { // 16位编码
block[0] = (aad_len >> 8) & 0xFF;
block[1] = aad_len & 0xFF;
memcpy(block + 2, aad, remaining > 14 ? 14 : remaining);

ccm_cbc_mac_update(mac, block, key);
remaining -= remaining > 14 ? 14 : remaining;
aad += remaining > 14 ? 14 : remaining;
} else { // 更大的AAD使用不同编码
// … 处理大AAD
}

// 处理剩余AAD块
while (remaining >= 16) {
ccm_cbc_mac_update(mac, aad, key);
aad += 16;
remaining -= 16;
}

// 处理最后部分块
if (remaining > 0) {
memset(block, 0, 16);
memcpy(block, aad, remaining);
ccm_cbc_mac_update(mac, block, key);
}
}

// CBC-MAC更新
static void ccm_cbc_mac_update(u8 *mac, const u8 *data, const u32 *key)
{
// CBC: mac = mac ⊕ data, 然后加密
for (int i = 0; i < 16; i++) {
mac[i] ^= data[i];
}

sm4_ce_encrypt_block(mac, mac, key, 32);
}

  CBC-MAC特点:

    1. 链式处理:CBC模式的认证计算     2. 长度编码:AAD长度的正确编码     3. 填充处理:最后块的正确填充     4. 并行友好:支持块级别的并行处理

6. 设计模式分析

6.1 策略模式在CCM实现选择中的体现

  SM4 CCM CE的策略模式:

// CCM实现策略接口
interface CcmImplementationStrategy {
void encrypt(u8[] ciphertext, u8[] plaintext, u32[] key, u8[] nonce, u8[] aad, u8[] tag);
void decrypt(u8[] plaintext, u8[] ciphertext, u32[] key, u8[] nonce, u8[] aad, u8[] tag);
boolean supportsHardwareAccel();
double getPerformanceFactor();
boolean requiresCeInstructions();
String getStrategyName();
}

// CE硬件加速策略
class CcmCeStrategy implements CcmImplementationStrategy {
public void encrypt(u8[] ciphertext, u8[] plaintext, u32[] key, u8[] nonce, u8[] aad, u8[] tag) {
sm4_ccm_ce_encrypt(ciphertext, plaintext, key, nonce, aad, aad.length, tag, tag.length);
}

public void decrypt(u8[] plaintext, u8[] ciphertext, u32[] key, u8[] nonce, u8[] aad, u8[] tag) {
sm4_ccm_ce_decrypt(plaintext, ciphertext, key, nonce, aad, aad.length, tag, tag.length);
}

public boolean supportsHardwareAccel() {
return true;
}

public double getPerformanceFactor() {
return 5.0; // 相对于软件实现的性能倍数
}

public boolean requiresCeInstructions() {
return true;
}

public String getStrategyName() {
return "SM4-CCM-CE";
}
}

// 软件实现策略
class CcmSoftwareStrategy implements CcmImplementationStrategy {
public void encrypt(u8[] ciphertext, u8[] plaintext, u32[] key, u8[] nonce, u8[] aad, u8[] tag) {
sm4_ccm_encrypt_software(ciphertext, plaintext, key, nonce, aad, tag);
}

public void decrypt(u8[] plaintext, u8[] ciphertext, u32[] key, u8[] nonce, u8[] aad, u8[] tag) {
sm4_ccm_decrypt_software(plaintext, ciphertext, key, nonce, aad, tag);
}

public boolean supportsHardwareAccel() {
return false;
}

public double getPerformanceFactor() {
return 1.0; // 基准性能
}

public boolean requiresCeInstructions() {
return false;
}

public String getStrategyName() {
return "SM4-CCM-Software";
}
}

// 策略选择器
class CcmStrategySelector {
public CcmImplementationStrategy selectStrategy(boolean ceAvailable, int dataSize) {
if (ceAvailable && dataSize >= 512) {
// 大数据量且支持CE:使用硬件加速
return new CcmCeStrategy();
} else {
// 默认使用软件实现
return new CcmSoftwareStrategy();
}
}
}

6.2 适配器模式在CE硬件抽象中的体现

  SM4 CCM CE的适配器模式:

// SM4 CCM硬件适配器接口
interface Sm4CcmHardwareAdapter {
void initCcmContext(u8[] key);
void processAssociatedData(u8[] aad, int aadLen);
void encryptPayload(u8[] ciphertext, u8[] plaintext, int len);
void computeAuthenticationTag(u8[] tag, int tagLen);
void decryptPayload(u8[] plaintext, u8[] ciphertext, int len);
boolean verifyAuthenticationTag(u8[] tag, int tagLen);
boolean isHardwareAccelerated();
void enterHardwareContext();
void exitHardwareContext();
}

// ARM64 CE适配器
class Arm64Sm4CcmCeAdapter implements Sm4CcmHardwareAdapter {

public void initCcmContext(u8[] key) {
// CE初始化CCM上下文
kernel_neon_begin();
sm4_ccm_ce_init_context(key);
kernel_neon_end();
}

public void processAssociatedData(u8[] aad, int aadLen) {
kernel_neon_begin();
sm4_ccm_ce_process_aad(aad, aadLen);
kernel_neon_end();
}

public void encryptPayload(u8[] ciphertext, u8[] plaintext, int len) {
kernel_neon_begin();
sm4_ccm_ce_encrypt_payload(ciphertext, plaintext, len);
kernel_neon_end();
}

public void computeAuthenticationTag(u8[] tag, int tagLen) {
kernel_neon_begin();
sm4_ccm_ce_compute_tag(tag, tagLen);
kernel_neon_end();
}

public void decryptPayload(u8[] plaintext, u8[] ciphertext, int len) {
kernel_neon_begin();
sm4_ccm_ce_decrypt_payload(plaintext, ciphertext, len);
kernel_neon_end();
}

public boolean verifyAuthenticationTag(u8[] tag, int tagLen) {
kernel_neon_begin();
boolean result = sm4_ccm_ce_verify_tag(tag, tagLen);
kernel_neon_end();
return result;
}

public boolean isHardwareAccelerated() {
return true;
}

public void enterHardwareContext() {
kernel_neon_begin();
}

public void exitHardwareContext() {
kernel_neon_end();
}
}

// 使用适配器模式
class Sm4CcmCe {
private Sm4CcmHardwareAdapter adapter;

public Sm4CcmCe() {
if (isArm64CeAvailable()) {
this.adapter = new Arm64Sm4CcmCeAdapter();
} else {
throw new UnsupportedOperationException("CE not available");
}
}

public void encrypt(u8[] ciphertext, u8[] plaintext, u8[] key, u8[] nonce, u8[] aad, u8[] tag) {
adapter.initCcmContext(key);

if (aad.length > 0) {
adapter.processAssociatedData(aad, aad.length);
}

adapter.encryptPayload(ciphertext, plaintext, plaintext.length);
adapter.computeAuthenticationTag(tag, tag.length);
}

public boolean decrypt(u8[] plaintext, u8[] ciphertext, u8[] key, u8[] nonce, u8[] aad, u8[] tag) {
adapter.initCcmContext(key);

if (aad.length > 0) {
adapter.processAssociatedData(aad, aad.length);
}

adapter.decryptPayload(plaintext, ciphertext, ciphertext.length);
return adapter.verifyAuthenticationTag(tag, tag.length);
}
}

6.3 工厂模式在AEAD算法实例化中的体现

  SM4 CCM CE的工厂模式:

// AEAD算法工厂
class AeadAlgorithmFactory {

// 创建AEAD算法实例
public AeadAlgorithm createAeadAlgorithm(AeadType type, AeadKeySize keySize,
AeadHardwarePreference hwPref) {
switch (type) {
case SM4_CCM:
return createSm4CcmAlgorithm(keySize, hwPref);
case AES_GCM:
return createAesGcmAlgorithm(keySize, hwPref);
case CHACHA20_POLY1305:
return createChaCha20Poly1305Algorithm(hwPref);
default:
throw new IllegalArgumentException("Unsupported AEAD type: " + type);
}
}

private AeadAlgorithm createSm4CcmAlgorithm(AeadKeySize keySize, AeadHardwarePreference hwPref) {
// 选择硬件适配器
AeadHardwareAdapter adapter = selectHardwareAdapter(hwPref);

// 选择CCM策略
CcmImplementationStrategy strategy = selectCcmStrategy(hwPref);

switch (keySize) {
case AEAD_KEY_128:
return new Sm4Ccm128Algorithm(adapter, strategy);
case AEAD_KEY_256:
return new Sm4Ccm256Algorithm(adapter, strategy);
default:
throw new IllegalArgumentException("Unsupported key size for SM4-CCM: " + keySize);
}
}

private AeadHardwareAdapter selectHardwareAdapter(AeadHardwarePreference pref) {
switch (pref) {
case CE_PREFERRED:
if (isCeAvailable()) {
return new CeHardwareAdapter();
}
// fallback
case NEON_PREFERRED:
if (isNeonAvailable()) {
return new NeonHardwareAdapter();
}
// fallback
default:
return new SoftwareAdapter();
}
}

private CcmImplementationStrategy selectCcmStrategy(AeadHardwarePreference pref) {
if (pref == CE_PREFERRED && isCeAvailable()) {
return new CcmCeStrategy();
} else {
return new CcmSoftwareStrategy();
}
}
}

// SM4-CCM具体算法实现
class Sm4Ccm128Algorithm extends AeadAlgorithm {
private AeadHardwareAdapter adapter;
private CcmImplementationStrategy strategy;

public Sm4Ccm128Algorithm(AeadHardwareAdapter adapter, CcmImplementationStrategy strategy) {
this.adapter = adapter;
this.strategy = strategy;
this.keySize = 16;
this.nonceSize = 12; // CCM推荐nonce大小
this.tagSize = 16; // 默认标签大小
}

public void encrypt(u8[] ciphertext, u8[] plaintext, u8[] key, u8[] nonce, u8[] aad, u8[] tag) {
// 扩展密钥
u32[] keySchedule = adapter.expandKey(key, keySize);

// 使用CCM策略进行加密
strategy.encrypt(ciphertext, plaintext, keySchedule, nonce, aad, tag);
}

public boolean decrypt(u8[] plaintext, u8[] ciphertext, u8[] key, u8[] nonce, u8[] aad, u8[] tag) {
// 扩展密钥
u32[] keySchedule = adapter.expandKey(key, keySize);

// 使用CCM策略进行解密和验证
return strategy.decrypt(plaintext, ciphertext, keySchedule, nonce, aad, tag);
}

public boolean isHardwareAccelerated() {
return adapter.isHardwareAccelerated();
}

public String getAlgorithmName() {
return "SM4-CCM-128-" + adapter.getName();
}
}

7. 状态机分析

  SM4 CCM CE处理的状态机:

初始状态 -> CE检测 -> CCM参数验证 -> 密钥扩展 -> AAD处理 -> CBC-MAC计算 -> CTR加密/解密 -> 标签验证 -> 结果输出
↑ ↓
错误处理 <—————————————————————————————————————–+
↑ ↓
硬件上下文 <—————————————————————————————————————-+
↑ ↓
性能监控 <—————————————————————————————————————–+

8. 性能优化分析

8.1 硬件指令优化

  SM4 CCM CE指令的性能特性:

// SM4 CCM CE性能分析
static void analyze_sm4_ccm_ce_performance(void) {
// 测量CCM模式的性能
ktime_t start, end;
u8 plaintext[1024];
u8 ciphertext[1024];
u8 aad[64];
u8 tag[16];
u8 key[16];
u8 nonce[12];

// 初始化测试数据
memset(plaintext, 0x12, sizeof(plaintext));
memset(aad, 0x34, sizeof(aad));
memset(key, 0x56, sizeof(key));
memset(nonce, 0x78, sizeof(nonce));

start = ktime_get();

// 执行SM4-CCM加密
for (int i = 0; i < 1000; i++) {
sm4_ccm_ce_encrypt(ciphertext, plaintext, sizeof(plaintext),
key, nonce, aad, sizeof(aad), tag, sizeof(tag));
}

end = ktime_get();

// 计算性能指标
s64 duration = ktime_to_ns(ktime_sub(end, start));
s64 cycles_per_byte = duration / (1000 * sizeof(plaintext));

pr_info("SM4-CCM CE performance: %lld cycles/byte\\n", cycles_per_byte);
pr_info("AEAD throughput: %.2f MB/s\\n",
(double)sizeof(plaintext) * 1000 * NSEC_PER_SEC / duration / 1024 / 1024);
}

8.2 内存访问模式优化

  内存访问优化:

// CCM内存访问优化
static void sm4_ccm_ce_memory_optimize(u8 **dst, const u8 *src, size_t len,
const u8 *aad, size_t aad_len) {
// CCM模式的内存访问优化
if (len >= 4096) {
// 大消息:优化AAD和payload的处理顺序
sm4_ccm_ce_process_large_message(dst, src, len, aad, aad_len);
} else if (aad_len >= 1024) {
// 大AAD:分块处理AAD
sm4_ccm_ce_process_large_aad(dst, src, len, aad, aad_len);
} else {
// 小消息:直接处理
sm4_ccm_ce_process_small_message(dst, src, len, aad, aad_len);
}
}

// 大消息处理优化
static void sm4_ccm_ce_process_large_message(u8 *dst, const u8 *src, size_t len,
const u8 *aad, size_t aad_len) {
// 分块处理以改善缓存局部性
const size_t chunk_size = 2048; // 2KB块

// 先处理AAD(CBC-MAC阶段)
sm4_ccm_ce_process_aad_chunks(aad, aad_len);

// 然后分块处理payload
size_t processed = 0;
while (processed < len) {
size_t current_chunk = min(chunk_size, len processed);

sm4_ccm_ce_process_payload_chunk(dst + processed, src + processed, current_chunk);

processed += current_chunk;
}

// 最终化MAC
sm4_ccm_ce_finalize_mac();
}

// AAD分块处理
static void sm4_ccm_ce_process_aad_chunks(const u8 *aad, size_t aad_len) {
// 预取AAD数据
__builtin_prefetch(aad, 0, 3);

size_t processed = 0;
while (processed < aad_len) {
size_t chunk_size = min(1024, aad_len processed); // 1KB AAD块

sm4_ccm_ce_update_mac(aad + processed, chunk_size);

processed += chunk_size;

// 预取下一块
if (processed + 1024 < aad_len) {
__builtin_prefetch(aad + processed + 1024, 0, 3);
}
}
}

8.3 并行处理优化

  多线程并行处理:

// CCM多线程并行处理
static int sm4_ccm_ce_parallel_process(u8 *dst, const u8 *src, size_t len,
const u8 *aad, size_t aad_len, const u8 *key,
const u8 *nonce, u8 *tag, bool encrypt) {
// 对于CCM,认证部分不能并行,但加密部分可以有限并行

if (len < 4096) {
// 小消息单线程处理
return sm4_ccm_ce_process_single(dst, src, len, aad, aad_len, key, nonce, tag, encrypt);
}

// 大消息:并行CBC-MAC计算(如果AAD很大)
if (aad_len >= 8192) {
sm4_ccm_ce_parallel_aad_processing(aad, aad_len, key);
} else {
// 串行CBC-MAC
sm4_ccm_ce_process_aad(aad, aad_len, key);
}

// CTR加密/解密可以并行
if (len >= 8192) {
return sm4_ccm_ce_parallel_payload(dst, src, len, key, nonce, tag, encrypt);
} else {
return sm4_ccm_ce_process_payload(dst, src, len, key, nonce, tag, encrypt);
}
}

// 并行AAD处理
static void sm4_ccm_ce_parallel_aad_processing(const u8 *aad, size_t aad_len, const u8 *key) {
// 将AAD分成多个块并行处理CBC-MAC
const int num_threads = min(4, aad_len / 2048); // 最多4线程,每线程最小2KB

if (num_threads <= 1) {
sm4_ccm_ce_process_aad(aad, aad_len, key);
return;
}

// 为每个线程准备CBC-MAC状态
struct cbc_mac_state states[num_threads];

#pragma omp parallel for
for (int i = 0; i < num_threads; i++) {
size_t offset = i * (aad_len / num_threads);
size_t chunk_len = (i == num_threads 1) ?
aad_len offset : aad_len / num_threads;

// 初始化每个块的CBC-MAC状态
sm4_ccm_ce_init_cbc_mac_block(&states[i], key, offset == 0);

// 处理AAD块
sm4_ccm_ce_process_aad_block(&states[i], aad + offset, chunk_len);
}

// 合并所有CBC-MAC状态
struct cbc_mac_state final_state = states[0];
for (int i = 1; i < num_threads; i++) {
sm4_ccm_ce_merge_cbc_mac_states(&final_state, &states[i]);
}

// 更新全局MAC状态
memcpy(&global_cbc_mac_state, &final_state, sizeof(struct cbc_mac_state));
}

9. 安全性考虑

9.1 CCM模式安全性

  SM4 CCM CE的安全性保障:

// CCM安全性验证
static int sm4_ccm_ce_security_validate(void) {
// 验证CCM实现与标准实现的等价性
u8 key[16];
u8 nonce[12];
u8 plaintext[64];
u8 aad[32];
u8 ciphertext[64];
u8 tag[16];
u8 decrypted[64];

// 生成测试数据
get_random_bytes(key, sizeof(key));
get_random_bytes(nonce, sizeof(nonce));
get_random_bytes(plaintext, sizeof(plaintext));
get_random_bytes(aad, sizeof(aad));

// CE实现加密
sm4_ccm_ce_encrypt(ciphertext, plaintext, sizeof(plaintext),
key, nonce, aad, sizeof(aad), tag, sizeof(tag));

// CE实现解密
int ret = sm4_ccm_ce_decrypt(decrypted, ciphertext, sizeof(plaintext),
key, nonce, aad, sizeof(aad), tag, sizeof(tag));

if (ret != 0) {
pr_err("SM4-CCM CE decrypt failed\\n");
return EINVAL;
}

// 验证解密结果
if (memcmp(plaintext, decrypted, sizeof(plaintext)) != 0) {
pr_err("SM4-CCM CE roundtrip failed\\n");
return EINVAL;
}

return 0;
}

// nonce唯一性检查
static int sm4_ccm_ce_validate_nonce(const u8 *nonce, size_t nonce_len) {
// 检查nonce是否重复使用(简化的检查)
static u8 last_nonce[16];
static size_t last_nonce_len = 0;

if (nonce_len == last_nonce_len &&
memcmp(nonce, last_nonce, nonce_len) == 0) {
pr_warn("CCM nonce reuse detected – potential security issue\\n");
// 在生产环境中应该拒绝重复nonce
}

memcpy(last_nonce, nonce, nonce_len);
last_nonce_len = nonce_len;

return 0;
}

9.2 认证标签安全

  认证标签的安全处理:

// 认证标签安全处理
static void sm4_ccm_ce_secure_tag_handling(u8 *tag, size_t tag_len, bool is_encrypt) {
if (is_encrypt) {
// 加密时:生成随机标签前清理内存
memzero_explicit(tag, tag_len);
} else {
// 解密时:验证标签后立即清理
// 标签验证逻辑在decrypt函数中

// 清理敏感数据
memzero_explicit(tag, tag_len);
}
}

// 恒定时间标签比较
static int sm4_ccm_ce_constant_time_tag_verify(const u8 *computed_tag,
const u8 *received_tag, size_t tag_len) {
// 使用恒定时间比较防止时间侧信道攻击
u8 result = 0;

for (size_t i = 0; i < tag_len; i++) {
result |= computed_tag[i] ^ received_tag[i];
}

// 清理临时变量
memzero_explicit(&result, sizeof(result));

return result == 0 ? 0 : EBADMSG;
}

9.3 故障检测

  硬件加速的故障检测:

// CCM故障检测
static bool sm4_ccm_ce_fault_detection(u8 *ciphertext1, u8 *ciphertext2,
const u8 *plaintext, const u8 *key,
const u8 *nonce, const u8 *aad, size_t aad_len,
u8 *tag1, u8 *tag2, size_t tag_len) {
// 双重计算验证
sm4_ccm_ce_encrypt(ciphertext1, plaintext, strlen(plaintext),
key, nonce, aad, aad_len, tag1, tag_len);

sm4_ccm_ce_encrypt(ciphertext2, plaintext, strlen(plaintext),
key, nonce, aad, aad_len, tag2, tag_len);

// 比较两次结果
if (memcmp(ciphertext1, ciphertext2, strlen(plaintext)) != 0 ||
memcmp(tag1, tag2, tag_len) != 0) {
pr_err("SM4-CCM CE fault detected – inconsistent results\\n");
return true;
}

// 验证解密
u8 decrypted[256];
int ret = sm4_ccm_ce_decrypt(decrypted, ciphertext1, strlen(plaintext),
key, nonce, aad, aad_len, tag1, tag_len);

if (ret != 0 || memcmp(decrypted, plaintext, strlen(plaintext)) != 0) {
pr_err("SM4-CCM CE fault detected – decrypt verification failed\\n");
return true;
}

return false;
}

// 运行时完整性监控
static void sm4_ccm_ce_integrity_monitor(void) {
static u64 last_check = 0;
u64 current_time = ktime_get_ns();

// 每15秒检查一次
if (current_time last_check > 15 * NSEC_PER_SEC) {
if (sm4_ccm_ce_security_validate() != 0) {
pr_err("SM4-CCM CE integrity check failed\\n");
// 禁用CE实现
sm4_ccm_ce_disable();
} else {
pr_info("SM4-CCM CE integrity check passed\\n");
}

last_check = current_time;
}
}

10. 扩展性分析

10.1 新指令集支持

  扩展支持新的ARM指令集:

// SVE指令集支持CCM
#ifdef CONFIG_ARM64_SVE
static void sm4_ccm_ce_sve_optimized(u8 *out, const u8 *in, size_t len,
const u8 *key, const u8 *nonce,
const u8 *aad, size_t aad_len, u8 *tag, size_t tag_len) {
// 使用SVE进行CCM处理
kernel_neon_begin();

__asm__ volatile (
".p2align 4 \\n"
"1: \\n"
// SVE向量加载
"ld1b z0.b, p0/z, [%[in]] \\n"

// SVE SM4-CCM处理
"sm4_ccm_sve_process z0.b, z1.b, z2.b \\n" // 假设的SVE指令

// 更新指针
"add %[in], %[in], x0 \\n"
"add %[out], %[out], x0 \\n"

// 循环控制
"subs %[len], %[len], x0 \\n"
"bgt 1b \\n"

: [in] "+r" (in), [out] "+r" (out), [len] "+r" (len)
: [key] "r" (key), [nonce] "r" (nonce), [aad] "r" (aad), [tag] "r" (tag)
: "z0", "z1", "z2", "x0", "p0", "memory"
);

kernel_neon_end();
}
#endif

10.2 多算法集成

  扩展支持其他AEAD算法:

// AEAD算法框架
struct aead_crypto_ops {
int (*setkey)(struct crypto_aead *tfm, const u8 *key, unsigned int keylen);
int (*setauthsize)(struct crypto_aead *tfm, unsigned int authsize);
int (*encrypt)(struct aead_request *req);
int (*decrypt)(struct aead_request *req);
int (*init)(struct crypto_aead *tfm);
void (*exit)(struct crypto_aead *tfm);
int ivsize;
int maxauthsize;
int chunksize;
};

// SM4-CCM CE操作
static const struct aead_crypto_ops sm4_ccm_ce_ops = {
.setkey = sm4_ccm_ce_setkey,
.setauthsize = sm4_ccm_ce_setauthsize,
.encrypt = sm4_ccm_ce_encrypt,
.decrypt = sm4_ccm_ce_decrypt,
.init = sm4_ccm_ce_init,
.exit = sm4_ccm_ce_exit,
.ivsize = SM4_CCM_IV_SIZE, // nonce大小
.maxauthsize = SM4_CCM_TAG_SIZE, // 最大认证标签大小
.chunksize = SM4_BLOCK_SIZE, // 块大小
};

// AES-GCM CE操作
static const struct aead_crypto_ops aes_gcm_ce_ops = {
.setkey = aes_gcm_ce_setkey,
.setauthsize = aes_gcm_ce_setauthsize,
.encrypt = aes_gcm_ce_encrypt,
.decrypt = aes_gcm_ce_decrypt,
.init = aes_gcm_ce_init,
.exit = aes_gcm_ce_exit,
.ivsize = AES_GCM_IV_SIZE,
.maxauthsize = AES_GCM_TAG_SIZE,
.chunksize = AES_BLOCK_SIZE,
};

10.3 性能监控和调优

  SM4 CCM CE性能监控:

// SM4 CCM CE性能监控
struct sm4_ccm_ce_stats {
atomic64_t encrypt_ops;
atomic64_t decrypt_ops;
atomic64_t auth_failures;
atomic64_t total_cycles;
atomic64_t mac_cycles;
atomic64_t ctr_cycles;
atomic64_t bytes_processed;
atomic64_t aad_bytes_processed;
};

// 性能统计
static void sm4_ccm_ce_update_stats(enum ccm_operation op, s64 cycles,
size_t data_bytes, size_t aad_bytes, int result) {
switch (op) {
case CCM_ENCRYPT:
atomic64_inc(&sm4_ccm_ce_stats.encrypt_ops);
break;
case CCM_DECRYPT:
atomic64_inc(&sm4_ccm_ce_stats.decrypt_ops);
if (result == EBADMSG) {
atomic64_inc(&sm4_ccm_ce_stats.auth_failures);
}
break;
}

atomic64_add(cycles, &sm4_ccm_ce_stats.total_cycles);
atomic64_add(data_bytes, &sm4_ccm_ce_stats.bytes_processed);
atomic64_add(aad_bytes, &sm4_ccm_ce_stats.aad_bytes_processed);
}

// 性能报告
static void sm4_ccm_ce_print_stats(void) {
pr_info("SM4-CCM CE Performance Stats:\\n");
pr_info(" Encrypt ops: %lld\\n", atomic64_read(&sm4_ccm_ce_stats.encrypt_ops));
pr_info(" Decrypt ops: %lld\\n", atomic64_read(&sm4_ccm_ce_stats.decrypt_ops));
pr_info(" Auth failures: %lld\\n", atomic64_read(&sm4_ccm_ce_stats.auth_failures));
pr_info(" Total cycles: %lld\\n", atomic64_read(&sm4_ccm_ce_stats.total_cycles));
pr_info(" Data bytes processed: %lld\\n", atomic64_read(&sm4_ccm_ce_stats.bytes_processed));
pr_info(" AAD bytes processed: %lld\\n", atomic64_read(&sm4_ccm_ce_stats.aad_bytes_processed));

u64 total_ops = atomic64_read(&sm4_ccm_ce_stats.encrypt_ops) +
atomic64_read(&sm4_ccm_ce_stats.decrypt_ops);

if (total_ops > 0) {
u64 avg_cycles_per_op = atomic64_read(&sm4_ccm_ce_stats.total_cycles) / total_ops;
u64 cycles_per_data_byte = atomic64_read(&sm4_ccm_ce_stats.total_cycles) /
atomic64_read(&sm4_ccm_ce_stats.bytes_processed);
u64 cycles_per_aad_byte = atomic64_read(&sm4_ccm_ce_stats.aad_bytes_processed) > 0 ?
atomic64_read(&sm4_ccm_ce_stats.total_cycles) /
atomic64_read(&sm4_ccm_ce_stats.aad_bytes_processed) : 0;

pr_info(" Average cycles/op: %lld\\n", avg_cycles_per_op);
pr_info(" Cycles/data byte: %lld\\n", cycles_per_data_byte);
pr_info(" Cycles/AAD byte: %lld\\n", cycles_per_aad_byte);

u64 auth_failure_rate = atomic64_read(&sm4_ccm_ce_stats.auth_failures) * 100 /
atomic64_read(&sm4_ccm_ce_stats.decrypt_ops);
pr_info(" Authentication failure rate: %lld%%\\n", auth_failure_rate);
}
}

11. 调试和维护

11.1 调试信息输出

  SM4 CCM CE的调试支持:

// 调试宏定义
#define SM4_CCM_CE_DEBUG(fmt, ...) \\
pr_debug("SM4-CCM-CE: " fmt, ##__VA_ARGS__)

#define SM4_CCM_CE_DEBUG_STATE(ctx) \\
do { \\
SM4_CCM_CE_DEBUG("key_len: %d, ivsize: %d, authsize: %d\\n", \\
ctx->key_len, ctx->ivsize, ctx->authsize); \\
SM4_CCM_CE_DEBUG("encrypt_ops: %lld, decrypt_ops: %lld\\n", \\
ctx->stats.encrypt_ops, ctx->stats.decrypt_ops); \\
SM4_CCM_CE_DEBUG("finalized: %d\\n", ctx->finalized); \\
} while (0)

#define SM4_CCM_CE_DEBUG_REQUEST(req) \\
SM4_CCM_CE_DEBUG("Request: cryptlen=%u, assoclen=%u, iv=%*ph\\n", \\
req->cryptlen, req->assoclen, \\
crypto_aead_ivsize(crypto_aead_reqtfm(req)), req->iv)

// 详细调试模式
#ifdef CONFIG_SM4_CCM_CE_DEBUG
static void sm4_ccm_ce_debug_operation(struct aead_request *req, bool is_encrypt,
const u8 *key, const u8 *nonce,
const u8 *aad, size_t aad_len,
const u8 *tag, size_t tag_len) {
SM4_CCM_CE_DEBUG("%s operation:\\n", is_encrypt ? "Encrypt" : "Decrypt");
SM4_CCM_CE_DEBUG(" Key: %*ph\\n", SM4_KEY_SIZE, key);
SM4_CCM_CE_DEBUG(" Nonce: %*ph\\n", crypto_aead_ivsize(crypto_aead_reqtfm(req)), nonce);

if (aad_len > 0) {
SM4_CCM_CE_DEBUG(" AAD (%zu bytes): %*ph\\n", aad_len, (int)min(aad_len, 16), aad);
}

if (!is_encrypt) {
SM4_CCM_CE_DEBUG(" Tag: %*ph\\n", tag_len, tag);
}

SM4_CCM_CE_DEBUG_REQUEST(req);

// 执行操作
int ret;
if (is_encrypt) {
ret = sm4_ccm_ce_do_encrypt(req);
if (ret == 0) {
SM4_CCM_CE_DEBUG(" Result tag: %*ph\\n", tag_len,
req->src + req->cryptlen tag_len);
}
} else {
ret = sm4_ccm_ce_do_decrypt(req);
SM4_CCM_CE_DEBUG(" Decrypt result: %s\\n", ret == 0 ? "success" : "failed");
}

SM4_CCM_CE_DEBUG(" Return code: %d\\n", ret);
}
#endif

11.2 错误检测和恢复

  错误处理机制:

// 输入验证
static int sm4_ccm_ce_validate_input(struct aead_request *req) {
struct crypto_aead *tfm = crypto_aead_reqtfm(req);

if (!req->src || !req->dst) {
SM4_CCM_CE_DEBUG("NULL source or destination buffer\\n");
return EINVAL;
}

// 检查长度
if (req->cryptlen == 0) {
SM4_CCM_CE_DEBUG("Empty cryptlen\\n");
return EINVAL;
}

// 检查nonce长度
size_t iv_len = crypto_aead_ivsize(tfm);
if (iv_len < 7 || iv_len > 13) {
SM4_CCM_CE_DEBUG("Invalid nonce length: %zu\\n", iv_len);
return EINVAL;
}

// 检查认证标签长度
size_t authsize = crypto_aead_authsize(tfm);
if (authsize != 4 && authsize != 6 && authsize != 8 &&
authsize != 10 && authsize != 12 && authsize != 14 && authsize != 16) {
SM4_CCM_CE_DEBUG("Invalid authsize: %zu\\n", authsize);
return EINVAL;
}

// 检查AAD长度是否合理
if (req->assoclen > SM4_CCM_MAX_AAD_LEN) {
SM4_CCM_CE_DEBUG("AAD too long: %u\\n", req->assoclen);
return EINVAL;
}

return 0;
}

// 上下文验证
static int sm4_ccm_ce_validate_context(struct sm4_ccm_ce_ctx *ctx) {
if (!ctx) {
SM4_CCM_CE_DEBUG("NULL context\\n");
return EINVAL;
}

if (ctx->key_len != SM4_KEY_SIZE) {
SM4_CCM_CE_DEBUG("Invalid key length: %d\\n", ctx->key_len);
return EINVAL;
}

// 验证CE可用性
if (!crypto_sm4_ce_available()) {
SM4_CCM_CE_DEBUG("CE not available\\n");
return ENODEV;
}

return 0;
}

// 错误恢复机制
static void sm4_ccm_ce_recover_from_error(struct sm4_ccm_ce_ctx *ctx, int error) {
SM4_CCM_CE_DEBUG("Attempting to recover from error %d\\n", error);

// 重置CBC-MAC状态
memset(ctx->mac, 0, sizeof(ctx->mac));
ctx->mac_initialized = false;

// 重置计数器状态
memset(ctx->ctr_nonce, 0, sizeof(ctx->ctr_nonce));
ctx->ctr_initialized = false;

// 重置统计信息
memset(&ctx->stats, 0, sizeof(ctx->stats));

// 重新初始化状态(如果密钥仍然有效)
if (ctx->key_len == SM4_KEY_SIZE) {
sm4_ccm_ce_init_state(ctx);
} else {
// 密钥无效,需要重新设置
memset(ctx->key, 0, sizeof(ctx->key));
ctx->key_len = 0;
}

SM4_CCM_CE_DEBUG("Recovery completed\\n");
}

12. 总结

  ARM64 crypto SM4 CCM CE子模块作为ARM64加密子系统的SM4-CCM认证加密模式CE硬件加速实现,通过ARMv8-A Crypto Extensions指令集优化CCM模式的认证加密功能。该模块实现了CBC-MAC认证和CTR模式加密的完整组合,为需要机密性和完整性保护的应用场景提供高性能的AEAD解决方案。源码分析显示,模块采用了策略模式、适配器模式和工厂模式等多种设计模式,为AEAD算法的硬件加速实现提供了灵活高效的架构。

赞(0)
未经允许不得转载:171主机测评 » Linux6.19-ARM64 crypto SM4 CCM CE子模块深入分析
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址