棋子 · 2023年10月16日

CXL学习(十一)

第十一章 安全

开始本章之前,需要对加密技术有所了解。

在数据传输中,有两点需要注意,一个是数据的保密性。如果发送方A以明文方式发送消息给接收方B,则容易被第三方C截获并分析出其中的内容。为了提高数据的安全性,需要对消息加密。

第二点是数据的完整性。发送方A将消息加密发送给接收方B,但是如果这个过程中有第三方C截获并且加以篡改(比如更改其中的一些bit或是更改密文块的顺序,此时C无需解密数据),然后再发送B,在B端是无法感知数据已经被破坏。这就需要有机制保证数据的完整性,即在传输过程中没有被破坏。单纯的数据校验不能保证完整性,这是因为C可以根据修改后的数据重新生成校验。

综上,安全的数据传输方式是A将数据加密,并且给加密后的数据打上一个特有的标签(tag),然后将密文和标签一起发送给B;B接收到数据后,先要检查标签,看看数据是否被修改过,确认数据的完整性后再将数据解密。

常见的加密可以分为两类,即对称加密和非对称加密。

  • 对称加密,也称单密钥加密,同一个密钥既可以用作加密也可以用作解密。因此对称加密的安全性不仅取决于加密算法本身,也和密钥管理相关。采用对称加密,收发双方需要在通信前协商一个密钥,并且双方负责该密钥的安全性。
  • 非对称加密算法使用两把完全不同但又是完全匹配的一对钥匙,公钥(public key)和私钥(private key)。加密明文时采用公钥加密,解密密文时使用私钥才能完成,而且发送方(加密者)知道接收方的公钥,只有接收方(解密者)才是唯一知道自己私钥的人。采用不对称加密,收发双方在通信之前,接收方必须将自己早已随机生成的公钥送给发送方,而自己保留私钥,留待解密用。

CXL采用的是AES-GCM加密方式。

AES属于对称加密。加密技术包括两个元素:算法和密钥。以下图为例,发送方将明文P(plain text)和密钥K(key)通过加密函数,生成密文C(cipher text);接收方在接收到密文C后,与密钥K通过解密函数,恢复明文P。

image.png

AES是一种分组加密技术,所谓分组就是将明文P分成长度相同的若干组,每次加密一组数据,直到加密完全部的明文。在AES规范中规定,分组长度只能是128-bit。AES支持的密钥长度可以是128-bit,192-bit或256-bit,密钥越长,加密轮数越多,安全性越高,当然消耗的时间也越多。

再来看加密模式,因为每次只能加密一组数据,而实际的明文可能很长,会分为很多组,此时就需要对这些分组进行迭代,已完成整个明文的加密。迭代的方法就是加密模式。

说完AES,再来看看什么是MACs(Message Authentication Codes,消息认证码)。消息认证码是一种允许对接收到的消息进行身份验证的信息,确保消息来自声称的发送者,而不是伪装成他们的第三方,同时确保消息没有以某种方式修改,以提供数据完整性。

消息认证码的输入为任意长度的消息和一个发送者与接收者之间共享的密钥,它可以输出固定长度的数据,这个数据称为MAC 值。用于生成消息认证码的密钥与用于验证消息认证码的密钥相同。从这个意义上讲,它类似于对称加密系统,并且密钥必须由所有通信方事先商定或以某种安全方式共享。

回过头来看AES-GCM,GCM是认证加密模式中的一种,其中G指的是GMAC,即利用伽罗华域(Galois Field,GF,有限域)乘法运算来计算消息的MAC值;C指的是CTR。

11.1 CXL IDE

CXL完整性和数据加密(Integrity and Data Encryption,IDE)定义了为传输CXL链路的数据提供机密性、完整性和重播保护的机制。加密方案与当前行业最佳实践保持一致。它支持各种使用模型,同时提供广泛的互操作性。CXL IDE可用于在由多个组件组成的可信执行环境(TEE)中保护流量,然而,这种组合的框架不在本规范的范围内。

11.1.1 范围

本章重点介绍通过链路传输的CXL.cache和CXL.mem流量传输,以及对控制CXL.io流量的PCIe基本规范的更新/限制。

  • CXL.io IDE的定义基于PCIe的IDE规范
  • CXL.cachemem IDE可以使用基于CXL.io的机制进行发现(discovery)、协商(negotiation)、设备证明(device attestation)和密钥协商(key negotiation)。

本规范中,CXL IDE指代保护CXL.io,CXL.cache,CXL.mem数据流的机制,CXL.cachemem IDE指代保护CXL.cache,CXL.mem数据流的机制。如果没有明确指出,则遵循PCIe规范。CXL.io基本上与PCIe IDE的要求一致。拒绝服务攻击(denial of services)不在范围内。

11.1.2 CXL.io IDE

CXL.io IDE遵循PCIe IDE定义。

image.png

解释几个名词。IDE流(IDE stream)指的是,使用完整性和数据加密定义的机制建立的端口到端口连接,以保护两个端口之间的TLP流量(traffic)。IDE流可以是selective IDE stream形式,IDE TLP可以在不影响其安全性的情况下流经交换机;也可以是Link stream形式,两个端口必须在没有中间交换机的情况下连接,也就是直连。参考下图,端口C和G之间以及端口G和H之间的selective IDE stream在通过交换机时是安全的。

image.png

Flow-Through 指的是对switch和RC,TLP从入口端口传递到出口端口而不进行修改的行为。

IDE terminus,作为与一个或多个IDE流相关联的IDE TLP的发起方或最终目的地的端口。

11.1.3 CXL.cache/CXL.mem IDE高层概览

  • 所有协议级别的重试flit都经过加密并受到完整性保护。
  • 链路层控制flit和flit CRC没有加密,也没有完整性保护。
  • LCRC应该在加密flit上计算。
  • 任何完整性检查失败的数据流都应被放弃。
  • 必须支持多数据头功能。这允许将多个(最多4个)数据头打包到一个slot中,然后紧接着是所有数据的16个slot。
  • 采用256-bit密钥的AES-GCM加解密
  • 必须支持在不丢失任何数据的情况下进行密钥刷新
  • 密钥刷新预计不经常发生。延迟/带宽受到影响是可以接受的,但不能有任何数据丢失。
  • 支持加密PCRC机制。加密PCRC集成到标准MAC检查机制中,不消耗额外链路带宽,不增加显著额外延迟。PCRC对于CXL.cachemem IDE是强制性的,并且在默认情况下是启用的

11.1.4 CXL.cache/CXL.mem IDE架构

  • IDE应当以flit为单位,使用AES-GCM模式。AES-GCM采用三个输入,分别为附加身份验证数据(Additional Authentication data,AAD,在AES-GCM规范中指定为A)、明文(P)和初始化矢量(IV)。在CXL.cachemem协议中,32-bit的数据包头作为slot 0的一部分,映射到A——它没有加密,但受到完整性保护。Slot 0/1/2/3的映射到P,P经过加密并受到完整性保护。CXL.cachemem协议也支持仅有数据(data-only)的flit,在这种情况下,flit中的所有4个slot映射到P。
  • LCRC不加密且不受到完整性保护。在flit被加密之后,对其计算CRC
  • IDE flit也遵守用于检测和纠正错误的链路层机制。
  • AES-GCM可以应用于多flit聚合,这些flit组成一个MAC_Epoch。可以聚合的flit数目取决于Aggregation Flit Count。如果启用PCRC,则32-bit的PCRC值应这些聚合的flit的末尾,以产生受完整性保护的最终P值。然而,PCRC的32-bit并不在链路上传输的。下图显示了在5个flit聚合MAC的情况下,flit内容到A和P的映射。图中深灰色部分是flit header,映射到A;浅灰色部分是数据,映射到P。

image.png

  • MAC是96-bit,MAC必须在H6类型的slot 0报头中传输。MAC本身既没有加密,也没有完整性保护。下图显示了在5个flit聚合MAC的情况下,flit内容到A和P的映射,其中一个flit携带MAC。图中橙色部分是MAC。

image.png

  • 下图给出了5个flit组成MAC Epoch示例的更详细视图。顶部显示的Flit 0是在该MAC Epoch中要发送的第一个flit。该图描绘了仅受完整性保护的标题字段,以及加密和受完整性防护的文本内容。Flit 0明文0字节0是明文的第一个字节。Flit 1明文0字节0应紧跟在Flit 0明文0字节11之后。

image.png

上面示例中,flit包头字节映射到AAD如下图。在上图中,只有Flit 0,2,3有flit包头。

11.1.5 加密的PCRC

使用系数为0x1EDC6F41的多项式进行PCRC计算。PCRC计算应从初始值0xFFFFFFFF开始。应在作为给定MAC Epoch的一部分的聚合flit中的所有明文字节上计算PCRC。PCRC计算应从flit明文内容的比特0字节0开始,并依次包括映射到明文的flit内容的每个字节的比特0-7。在跨flit内容累积32位值之后,应通过对累积值的位取1的补码来最终确定PCRC值,以获得PCRC[31:0]。

在发送端,PCRC值应附加到聚合的flit明文内容的末尾,进行加密并包含在MAC计算中。加密的PCRC值不在链路上传输。

image.png

在接收端,应根据接收到的解密密文重新计算PCRC值。当前MAC epoch的最后一个flit已被处理时,累积的PCRC值应与AES密钥流比特进行异或(加密),AES密钥流位紧跟在用于解密所接收的密码flit的值之后。为了MAC计算的目的,该加密的PCRC值应被附加到接收到的密文的末尾。

image.png

11.1.6 CXL.cachemem加密密钥和IV

CXL.cachemem IDE流的初始化涉及多个步骤。第一步是建立包含两个端口的组件的标识和认证,这两个端口充当CXL.cachemem IDE流的端点。第二步是建立IDE流的密钥。在某些情况下,这两个步骤可以合并。第三,配置IDE。最后,开始IDE流传输。

CXL.cachemem IDE可以利用CXL.io IDE机制进行设备认证和密钥交换。CXL.cachemem IDE的IV(初始化矢量)构造应遵循CXL.io PCIe规范。根据AES-GCM规范,使用确定性结构的96-bit IV。

  • [95:92]位包含子流标识符,1000b,[91:64]位均为0。相同的子流编码用于发送和接收的flit,但端口在发送和接收流期间使用的密钥必须不同。
  • [63:0]位包含一个单调递增的计数器。在建立IDE流时,每个子流的调用字段最初设置为值0000_0001h,并且每次使用IV时都会递增。

11.1.7 CXL.cache/CXL.mem IDE模式

CXL.cachemem IDE支持两种操作模式。

  • Containment模式:此模式下,只有在完整性检查通过后,数据才会发布以供进一步处理。此模式会影响延迟和带宽。延迟影响是由于在接收并检查完完整性值前,需要缓冲多个flit。带宽影响是由于完整性值被频繁发送。如果支持并启用了containment模式,则设备(和主机)将使用Aggregation Flit Counter为5。因为此模式需要缓冲接收到的flit,所以AFC数量不会太大。
  • Skid模式:滑动模式允许释放数据进行进一步处理,而无需等待完整性值的接收和检查。这样可以减少完整性值的传输频率。滑动模式允许接近零的延迟开销和非常低的带宽开销。在此模式下,被恶意修改的数据可能会被软件所接受和处理,但当接收并检查完整性值后才会检测到此类攻击。因此,当使用此模式时,软件和应用程序堆栈必须能够在狭窄的时间窗口内容忍攻击,否则结果是未定义的。如果支持并启用了skid模式,则设备(和主机)将使用Aggregation Flit Counter为128。
11.1.7.1 完整性模式的发现和设置

每个端口应通过CXL IDE的capability寄存器枚举其支持的模式和其它能力。所有符合本规范的设备应支持containment模式。

11.1.7.2 操作模式的协商和设置

在启用CXL.cachemem IDE之前,在CXL IDE的capability寄存器中配置操作模式和时序参数。

11.1.8 MAC聚合规则

  • MAC_Epoch:一组连续的flit用于flit聚合。给定的MAC报头应包含恰好一个MAC_Epoch的标签。在发送之前,发送方应在一个MAC_Epoch(最多N个flit)中积累flit上的完整性值。
  • 在所有情况下,发送方必须按照与MAC Epochs相同的顺序发送MAC。
  • 下图显示了在存在背靠背协议流量的情况下,一个MAC_Epoch的MAC生成和传输示例。要发送或接收的最早的flit显示在图的顶部。因此,属于MAC_EPOCH 1的flit 0到N-1(以黄色显示)按该顺序发送。MAC是在flit 0到N-1上计算的。

image.png

  • 发送方应尽早发送包含该完整性值的MAC报头。本规范允许在当前MAC_Epoch的最后一个flit的传输和该MAC_EpochMAC报头的实际传输之间传输属于下一个MAC_Epoch的协议flit。这可以避免由于MAC计算延迟而导致的带宽浪费。建议发送方在MAC计算完成后立即在第一个可用的Slot 0报头上发送MAC报头。在所有情况下,允许在发送先前MAC_Epoch MAC之前发送当前MAC_Epoch的最多5个协议flit。上图右侧就是发送了5个当前属于MAC_Epoch flit的情况。
  • 接收方可以期望在先前MAC_Epoch的最后一个flit之后的从第一到第六个协议flit中的任一个flit接收到先前MAC_Epoch的MAC。还是对应上面的最多5个flit。

image.png

  • 在containment模式中,接收方必须不释放(即给后续的功能模块)给定MAC_Epoch的flit,直到已经接收到包含这些flit的完整性值的MAC报头并且完整性检查已经通过。由于在接收先前MAC_Epoch的MAC报头之前,接收器可以接收属于当前MAC_Epoch的5个协议flit,因此接收方应缓冲当前MAC_Epoch的flit,以确保没有数据丢失。
  • 在skid模式中,一旦接收到flit,接收器就可以解密并释放flit。MAC值应根据需要进行累积,并在MAC_Epoch中的MAC报头到达时进行完整性检查。

11.1.9提前终止MAC

当前MAC_Epoch中传输的Flit少于聚合Flit计数时,允许发射机提前终止MAC_Epoch并在截断的MAC_Epoch中传输Flit的MAC。这是链路空闲(Link Idle)处理的一部分。在当前MAC_Epoch中传输了少于聚合Flit计数的多个协议Flit之后,链路可以准备进入空闲。

以下规则应适用于MAC_Epoch的提前终止和MAC的传输

当且仅当目前MAC_Epoch中的flit数少于Aggregation Flit Counter的数目(5或128,根据IDE模式),发送端才可以提前终止MAC。

下图是在3个协议flit之后截断当前MAC Epoch的示例。当前MAC Epoch中的flit可以是任何有效的协议flit,包括用于先前MAC Epoch的MAC的报头flit。对当前MAC Epoch的MAC使用截断MAC Flit发送。截断的MAC flit将在当前MAC Epoch的三个协议flit之后发送,而没有来自下一个MAC Epoch的其它协议flit。

image.png

对于在链路在发送Aggregation Flit Count数量后变为空闲的情况下,则不得使用如上定义的截断MAC flit。MAC标头必须是下一个MAC Epoch的一部分。允许使用截断的MAC Flit提前终止此新的MAC Epoch,见下图。规范在这里说的很拗口,直白一点就是,仅当MAC_Epoch中的flit数少于Aggregation Flit Counter的数目时才可以使用截断的MAC flit。

image.png

在提前MAC终止和传输截断MAC之后,发射机必须发送至少TruncationDelay数量的IDE空闲flit,然后才能传输任何协议flit。TruncationDelay计算公式如下:

TruncationDelay = Min(Remaining Flits, Tx Min Truncation Transmit Delay)

Remaining Flits= Aggregation Flit Count - Number of protocol flits received in

current MAC Epoch

11.1.10 Handshake to Trigger the Use of Keys

每个端口都公开了一个寄存器接口,软件可以使用该接口对发送和接收密钥及相关参数进行设置。在激活之前,这些密钥在寄存器中保持挂起状态。当密钥在上游和下游端口中交换和配置时,链路可以主动使用先前配置的密钥。

下面描述的机制用于将备份密钥切换到活动状态。

在密钥被编程到链路两侧的挂起寄存器中后,每个端口上的每个发射机上都应有一个特定于设备的动作,以触发IDE.Start链路层控制微片的传输。

在发送了IDE.Start之后,所有后续的协议flit都将受到新密钥的保护。为了让接收器准备好接收用新密钥保护的微片,发送器需要在发送任何带有新密钥的协议flit之前,发送IDE.idle flit。表54中定义了,在发送具有新密钥的任何协议flit之前,由寄存器字段Tx Key Refresh Time指定的flit数量。这些空闲的flit没有被加密或受到完整性保护。发射器中的TxKey Refresh Time必须配置为高于接收器中最坏情况延迟的值,以便准备使用新密钥,接收器通过Rx Min Key Refresh Time寄存器字段公布新密钥。在接收到IDE.Start flit之后,接收器必须切换到使用新的密钥。IDE.start flit应针对协议flit进行排序。在链路级retry的情况下,接收器应在处理IDE.start flit并切换到新密钥之前完成先前发送的协议flit的retry。

11.1.11 错误处理

CXL IDE不会影响或是要求对链路CRC错误处理和链路retry流程进行任何更改。

有关CXL.cachemem错误的详细信息记录在CXL IDE的Error Status寄存器中。当检测到CXL.cachemem IDE错误时,也会设置Uncorrectable Error Status寄存器中的相应位,并使用标准的CXL.cachemem协议错误信号机制发出错误信号。

在检测到完整性失败时:

  • 在错误报告寄存器中记录完整性检查失败,并使用标准CXL.cachemem协议错误信号机制发出错误信号。
  • 丢弃任何缓冲的协议flit,并丢弃所有后续的数据流,直到链路重置。
  • 设备应防止密钥或用户数据泄露。设备可能需要实现清除数据/状态的机制,或者具有访问控制以防止机密泄露。

以下情况必须视为完整性失败:

  • 当链路不处于安全模式时接收到MAC包头
  • 未收到预期的MAC包头
  • 接收到未预期的截断MAC Flit
  • 在截断MAC flit之后,协议flit的接收时间早于预期
  • 密钥切换后,协议flit的接收时间早于预期

我的理解,以上的情况均为可能链路收到攻击。

11.1.12 交换机支持

支持CXL.cachemem IDE的CXL交换机必须支持用于CXL.io的Link Stream IDE。

交换机可以选择性地支持CXL.io的Selective Stream IDE。对于CXL.io,CXL交换机可以仅支持流通(flow-through)模式下的Selective Stream IDE。在这种情况下,不能在主机端启用CXL.cachemem IDE。

对具有多VCS功能的交换机,可以在每个根端口的基础上启用CXL IDE。但是,一旦任何根端口启用了CXL IDE,从交换机到支持CXL IDE的MLD设备的下游链路就必须启用链路IDE。因此,来自未启用CXL IDE的根端口的数据流将被加密,并在交换机和设备之间受到完整性保护。

总结:本章内容为CXL数据加解密。CXL采用AES-GCM模式进行数据加解密,CXL.io的IDE基本与PCIe的IDE一致,因此本章主要是对CXL.cachemem IDE进行约束。

后面的章节我目前不太感兴趣,就不深究了。CXL协议一刷到此结束,很多细节还没有搞清楚,留待以后再说。总的说来,想要深入了解CXL,必须先要了解PCIe。不多说了,看PCIe规范去了。

【本系列完】

作者:老秦谈芯
文章来源:老秦谈芯

推荐阅读

更多IC设计干货请关注IC设计专栏。欢迎添加极术小姐姐微信(id:aijishu20)加入技术交流群,请备注研究方向。
推荐阅读
关注数
20187
内容数
1307
主要交流IC以及SoC设计流程相关的技术和知识
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息