【论文分享】Cure: A Security Architecture with CUstomizable and Resilient Enclaves 21‘USENIX

目录

Abstract

对于从低端嵌入式设备到功能强大的云服务器的各种计算机系统来说,提供可信执行环境(TEE)的安全架构一直是一个颇具吸引力的研究课题。这些架构的目标是保护隔离执行上下文(称为飞地)中的敏感服务。不幸的是,现有的 TEE 解决方案存在严重的设计缺陷。首先,它们遵循一刀切的方法,仅提供单一飞地类型,但是,不同的服务需要能够根据其需求进行调整的灵活飞地。其次,它们无法有效支持新兴应用程序(例如机器学习即服务),这些应用程序需要到外围设备(例如加速器)的安全通道或多核的计算能力。第三,它们对缓存侧通道攻击的保护要么是事后才想到的,要么是不切实际的,即,没有提供缓存资源和各个飞地之间的细粒度映射。

在这项工作中,我们提出了第一个安全架构 CURE,它通过提供不同类型的飞地来解决这些设计挑战:(i) 子空间飞地在所有执行权限级别提供垂直隔离,(ii) 用户空间飞地提供隔离执行非特权应用程序,以及 (iii) 自包含飞地允许跨越多个特权级别的隔离执行环境。此外,CURE 还可以将系统资源(例如外设、CPU 内核或缓存资源)独占分配给单个 enclave。 CURE 需要最少的硬件更改,同时显着提高硬件辅助安全架构的技术水平。我们在基于 RISC-V 的 SoC 上实现了 CURE,并在硬件和性能开销方面彻底评估了我们的原型。 CURE 在标准基准测试中施加了 15.33% 的几何平均性能开销。

Introduction

几十年来,对现代计算机系统的软件攻击一直是一个持续的挑战,导致持续不断的攻击与防御之间的竞赛。在商品操作系统的大型代码库中不断发现的可利用错误已证明它们不适合对敏感服务进行可靠保护 [104, 105]。这促使各种硬件辅助安全架构将硬件安全原语紧密集成到片上系统 (SoC) 中。基于功能的系统,例如 CHERI [100]、CODOM [95]、IMIX [30] 或 HDFI [82],通过(进程内)沙箱提供细粒度的保护,但是它们无法防御特权软件对手(例如,恶意操作系统)。相比之下,提供可信执行环境 (TEE) 的安全架构支持隔离容器,也称为 enclave。飞地允许对特权软件层中的对手提供粗粒度但强大的保护。 TEE 架构已被提出用于各种计算平台【资源受限嵌入式系统的 TEE 架构(例如 Sancus [66]、TyTAN [8]、TrustLite [47] 或 TIMBER-V [98])不是本文的主题。】,特别是现代高性能计算机系统,例如 Intel SGX [35]、AMD SEV [38]、ARM TrustZone [3] 等行业解决方案,或学术解决方案,例如Sanctum [22]、Sanctuary [10]、Keystone [48] 或 Komodo [27] 等等。

在本文中,我们重点关注现代高性能计算机系统的 TEE 架构。我们研究了现有 TEE 架构的缺点,并提出了一种增强且更加灵活的 TEE 架构,以及开放 RISC-V 架构的原型实现。

Deficiencies of existing TEE architectures

到目前为止,现有的 TEE 架构都采用了一刀切的 enclave 方法。它们仅提供一种类型的飞地,要求应用程序和服务适应这些飞地的功能和限制,例如,英特尔SGX限制其飞地的系统调用,因此,应用程序在移植到SGX时需要进行修改,这会产生额外的成本。需要采取其他措施,例如 Microsoft 的 Haven 框架 [5] 或 Graphene [87],才能将未经修改的应用程序部署到 SGX enclave。此外,今天,我们正在使用多种处理敏感数据的服务,例如支付、生物识别身份验证、智能合约、语音处理、机器学习即服务 (MLaaS) 等等。每个服务对底层 TEE 架构都有不同的要求。一项重要要求涉及安全连接到设备的能力。例如,在移动设备上,通过各种传感器不断收集隐私敏感数据,例如音频[9]、视频[83]或生物识别数据[19]。在云服务器上,大量敏感数据被聚合并用于训练专有的机器学习模型,通常在 CPU 之外,卸载到硬件加速器 [84]。然而,SGX [35]、SEV [38] 和 Sanctum [22] 等 TEE 架构根本不考虑安全 I/O,Keystone [48] 等解决方案需要额外的硬件来支持支持 DMA 的外设、解决方案像 Graviton [96] 一样需要在外围侧进行硬件更改。 TrustZone [3]、Sanctuary [10] 和 Komodo [27] 无法将外围设备直接绑定到各个飞地。

TEE 架构的另一个重要要求是针对旁路攻击提供充分且实用的保护,例如缓存 [11,50] 或受控旁路攻击 [65,92,101]。当前的 TEE 架构要么不在其威胁模型中包含缓存侧通道攻击(如 SGX [35] 或 TrustZone [3]),要么仅提供严重影响操作系统的不切实际的解决方案(如 Sanctum [22]),或者不考虑受控侧信道攻击,例如 SEV [38]。我们将在第9节中详细阐述相关工作以及现有TEE架构的问题。

This work.

在本文中,我们提出了一种 TEE 架构,称为 CURE,它通过具有成本效益且与架构无关的设计来解决现有解决方案的问题。 CURE 提供多种类型的飞地:(i) 仅隔离部分执行上下文的子空间飞地,(ii) 紧密集成到操作系统中的用户空间飞地,以及 (iii) 自维持飞地,它可以跨越多个 CPU 核心和特权级别。因此,CURE 是第一个在调整 enclave 边界方面提供高度自由的 TEE 架构,以满足 MLaaS 等现代敏感服务的个性化功能和安全要求。 CURE 可以将具有或不具有 DMA 支持的外设专门绑定到各个 enclave。此外,它还通过灵活且细粒度的缓存资源分配提供侧通道保护。

Challenges.

构建具有所描述属性的 TEE 架构面临着许多挑战。 (i) 必须开发新的硬件安全原语,使飞地能够适应不同的功能和安全要求。 (ii) 尽管安全原语应允许灵活的飞地,但它们不得要求侵入性硬件修改,否则会阻碍跨平台采用。 (iii) 虽然硬件的变化应该保持较小,但管理软件飞地的性能开销必须最小化。 (四) 保护在设计所有类型的飞地时,必须考虑针对侧通道和瞬时执行攻击形式的微架构攻击的新兴威胁。

Contributions.

我们的 CURE 设计及其在 RISC-V 平台上的实现解决了所有这些挑战。总而言之,我们的主要贡献如下:

我们提出了 CURE,这是我们针对灵活的 TEE 架构的新颖的与架构无关的设计,它可以保护多种 enclave 类型中未经修改的敏感服务,范围从用户空间中的 enclave、子空间 enclave 到独立(多核)enclave包括特权软件级别并支持 enclave 到外设绑定。

我们为 CPU 内核、系统总线和共享缓存引入了新颖的硬件安全原语,需要最少且非侵入性的硬件修改。

我们使用开源 Rocket Chip 生成器为开放 RISC-V 平台构建了 CURE 原型 [4]。

我们根据添加的逻辑和代码行来评估 CURE 的硬件和软件组件,以及使用微基准和宏基准测试的 FPGA 和周期精确模拟器设置上的 CURE 性能开销。

System Assumptions

CURE 针对现代高性能多核系统,具有常见的性能优化,如数据和指令缓存、转换后备缓冲区 (TLB)、共享缓存、分支预测器、刷新核心独占资源的相应指令以及中央系统连接 CPU 与主内存(通过专用内存控制器)和各种外设的总线。

System bus and peripherals

系统总线通过一组固定的硬连线外设控制器将 CPU 连接到大量系统外设。外围设备的范围从存储、通信和输入设备到专用计算单元,例如硬件加速器[37]。 CPU 使用部分内部外设存储器与外设交互,这些存储器映射到 CPU 的地址空间,称为内存映射 I/O (MMIO)。我们假设 CPU 可以清空外设的内部存储器来清理其状态。从 CPU 到外设的每次访问都在系统总线中解码并委托给相应的外设。 CPU 充当系统总线上的父级,而外设(和主内存)充当子级,响应来自父级的请求。然而,对于一些需要与CPU共享大量数据的外设来说,MMIO是不够的,因为CPU需要将数据从主存储器复制到外设存储器。因此,这些外设通常通过直接内存访问 (DMA) 控制器作为父设备连接到系统总线,从而允许它们直接访问主内存。为了应对这些复杂互连中的资源争用,系统总线还采用仲裁机制来调度当多个总线请求同时发生时建立父子连接。

Software privilege levels.

Figure 1: Software privilege levels (PL): user space, kernel space & dedicated levels for hypervisor & firmware.

我们假设 CPU 支持如图 1 所示的特权级别 (PL)。与现代处理器(Intel [21]、AMD [34] 或 ARM [55])一致,我们假设用户空间层( PL3)和特权更高的内核空间层(PL2),由 MMU(由 PL2 软件配置)通过虚拟地址空间执行。 CPU 可以支持虚拟机管理程序软件 (PL1) 的不同层,以在虚拟机 (VM) 中运行虚拟化操作系统,其中与 PL2 的分离由第二级硬件辅助地址转换执行 [73]。最后,我们假设一个高特权层(PL0),其中包含执行特定任务的固件,例如硬件仿真或电源管理。

我们假设系统在复位时执行安全引导,而存储在 CPU 只读存储器 (ROM) 中的第一个引导加载程序通过信任链验证固件 [53]。验证后,固件从固件代码中的预定义地址开始执行,并从非易失性存储器 (NVM) 加载当前固件状态,该状态以加密方式存储,并受到完整性和回滚保护。用于解密和验证固件状态的加密密钥由引导加载程序传递,引导加载程序将固件加载到随机存取存储器 (RAM) 中。例如,可以通过使用具有重放保护内存块(RPMB)分区的非易失性内存或使用 eFuse 作为安全单调计数器来实现回滚保护 [56]。当执行系统关闭时,固件将其状态存储在 NVM 中,并进行加密并受到完整性和回滚保护。

Adversary Model

我们的对手模型遵循 TEE 架构通常假设的模型,即一个强大的纯软件对手,可以危害所有软件组件,包括操作系统,除了配置硬件安全原语的小型软件/微码可信计算库 (TCB) 之外系统的一部分,管理飞地并且本质上是可信的[3,10,22,27,35,48]。

我们假设对手的目标是从 TCB 或受害者飞地泄露秘密信息。完全控制系统软件的对手可以将自己的代码注入内核(PL2)甚至虚拟机管理程序(PL1)。这使得对手能够完全访问用于设置 enclave 的 TCB 接口,从而产生恶意进程甚至 enclave。即使对手无法更改固件代码(使用安全启动),代码中仍然可能存在内存损坏漏洞,并且可以被对手利用[24]。此外,我们假设对手能够通过软件破坏外围设备来执行 DMA 攻击 [63, 76]。

我们假设底层硬件是正确且可信的,因此排除利用硬件缺陷的攻击 [40, 86]。我们也不假设物理访问,因此故障注入攻击 [6]、物理旁路攻击 [46, 62] 或恶意外围设备的物理连接超出了范围。我们不考虑攻击者造成飞地饥饿的拒绝服务 (DoS) 攻击,因为控制操作系统的攻击者可以轻松关闭整个系统。作为 TEE 架构的标准,CURE 不能防止 enclave 代码中的软件可利用漏洞,但可以防止其利用损害整个系统。

Requirements Analysis

为了提供可定制、实用且强隔离的飞地,CURE 必须满足许多安全和功能要求。我们在下一节中列出它们,并在第 7 节中展示 CURE 如何满足安全要求。在第 6 节和第 8 节中,我们演示了如何满足功能需求。

Security Requirements (SR)

SR.1: Enclave protection.

Enclave 代码在静止时必须受到完整性保护,并且在执行时对手无法访问。所有敏感飞地数据必须始终保持机密性和完整性。必须保护 enclave 免受所有软件层 (PL3PL0) 上的对手、其他潜在恶意 enclave 和 DMA 攻击 [63, 76]。

SR.2: Hardware security primitives.

飞地的保护必须由安全硬件组件强制执行,而安全硬件组件只能由软件 TCB 进行配置。

SR.3: Minimal software TCB.

TCB 必须受到保护,免受所有软件层 (PL3-PL0) 中的对手的攻击,并且其大小必须最小化,才能进行正式验证,即几个 KLOC [44]。

SR.4: Side-channel attack resilience.

必须针对最相关的软件侧通道攻击采取缓解措施,即对缓存资源的侧通道攻击 [31, 50, 70, 102]、受控侧通道攻击 [65, 92, 101] 和瞬时执行攻击[12、14、43、45、78、89、90、93]。

Functionality Requirements (FR)

FR.1: Dynamic enclave boundaries.

enclave 的信任边界必须可自由配置,以便 enclave在不同优先级别均被支持。

FR.2:Enclave-to-peripheral binding.

必须明确支持飞地与选定系统外设之间的安全通信,例如在将敏感的机器学习任务卸载给硬件加速器时[84]。

FR.3:Minimal hardware changes.

将建议的安全基元集成到通用 SoC(参见第 2 节)所需的硬件改动必须是最小的,不需要对 CPU 内部进行侵入性改动,这样才能使 CURE 在未来平台中得到更广泛的采用。

FR.4:Reasonable performance overhead.

在飞地设置和运行期间产生的性能开销必须降到最低,并且不得使计算机系统在某些使用情况下变得不实用或降低用户体验。

FR.5:Configurable protection mechanisms.

针对高速缓存侧信道攻击的保护机制必须在运行时动态适用,并以每个飞地为基础。

Design of the Cure Architecture

在这里插入图片描述

Cure Ecosystem

Customizable and Resilient Enclaves

四种Enclave,Encl1保护用户空间进程,Encl2运行在内核空间,Encl3跨内核和用户空间,Encl4只包括一部分的固件代码。

所以,一个enclave不需要包括优先级中的所有代码。

Enclave Management

在描述 CURE 支持的不同 enclave 类型之前,我们先概述一下 CURE 的 enclave 管理。

Security monitor.

与其他 TEE 架构一样,所有 CURE enclave 均由称为安全监视器 (SM) 的软件 TCB 进行管理 [22, 48]。如图 2 所示,SM 本身代表一个飞地,它是固件的一部分。如第 2 节中所述,我们假设系统在重置时执行安全启动,验证固件(包括 SM),然后跳转到 SM 的入口点。此外,我们假设SM已经将其回滚保护状态Ssm加载到易失性主存储器中。 SM 状态包含 SKd、PKd、Certd、Chainp 以及设备上安装的每个 enclave 的结构 Dencl。

Enclave installation.

当 enclave 部署到设备时,SM 首先使用 Certp 和 Chainp 验证签名 Sigencl。然后,SM创建一个新的Enclave元数据结构Dencl,并在其中存储Lencl、Sigencl和Certp。此外,SM还创建了一个Enclave状态结构Sencl,用于持久存储所有敏感的Enclave数据。 SM 还创建一个经过身份验证的加密密钥 Kencl,用于在存储到磁盘或闪存时保护 enclave 状态。 Kencl 和 Sencl 也存储在 Dencl 中。最初,Sencl 仅包含由 SM 创建的经过身份验证的加密密钥 Kcom,飞地使用该密钥来加密和完整性保护与不可信操作系统通信的数据,以及单调计数器。 enclave元数据结构Dencl还包含一个单调计数器,用于回滚保护enclave状态。

Enclave setup & teardown.

enclave 的设置始终由相应的主机应用程序触发。操作系统加载 enclave 二进制文件和配置文件后,会执行到 SM 的上下文切换。 SM 通过标签 Lencl 识别飞地,并通过 (1) 配置硬件安全原语(第 5.3 节)开始飞地设置,以便将一个或多个连续物理内存区域(根据配置文件)专门分配给飞地为了将飞地与系统软件的其余部分隔离。由于二进制文件和配置文件是从不受信任的软件加载的,因此必须始终使用 Sigencl 和 Certp 验证其完整性。当提供能够执行特权软件的飞地(内核空间飞地)时,分配物理内存区域是不可避免的,因为这允许飞地控制MMU。因此,虚拟内存无法用于有效隔离飞地。 (2)飞地验证后,SM配置硬件原语,以根据配置文件将其余系统资源(例如缓存或外设)分配给飞地。所有分配的资源也在 Dencl 中注明。此外,SM 为 enclave 分配一个标识符,该标识符存储在 Dencl 中,并且对于设备上当前活动的每个 enclave 来说都是唯一的。 SM 可以并行管理多达 N 个(实现定义的)飞地。我们提供了更多详细信息第 5.3 节中 enclave 标识符的含义。 (3)最后一步,恢复enclave状态Sencl,即从磁盘或闪存加载,使用Kencl解密和验证,然后复制到enclave内存,以便在enclave运行时可访问。 SM 还检查 Sencl 中的单调计数器是否与 Dencl 中存储的计数器匹配。

当飞地运行时,SM 将所有中断配置为路由到 SM。因此,SM 完全控制进出飞地的上下文切换。当执行 SM 时,执行 SM 的 CPU 内核上的所有中断都被禁用。所有其他内核保持中断响应。在 CURE 中,硬件辅助超线程在 enclave 执行期间被禁用,以防止通过硬件线程之间共享的资源泄漏数据。或者,如果 enclave 代码受益于并行化,则也可以将 CPU 核心的所有硬件线程分配给 enclave。在论文的提醒中,我们假设超线程在 enclave 运行时被禁用。

设置完成后,SM跳转到enclave的入口点。在 enclave 拆卸期间(可以由主机应用程序或 enclave 本身触发),SM 安全地存储 enclave 状态(使用 Kencl),同时递增 Sencl 和 Dencl 中的单调计数器,从内存和缓存中删除所有 enclave 数据,重新配置硬件原语。

Enclave execution.

在运行时,Enclave 可以通过其 API 访问 SM 提供的服务,例如,动态增加 Enclave 的内存或接收 SM 通过使用 SKd 签署 Sigencl 并附加 Certd 创建的完整性报告。然后,安全区将完整性报告发送给服务提供商。随后,服务提供商可以使用 Chaind 对 enclave 执行远程证明。仅当证明成功时,服务提供商才会向飞地提供敏感数据。还可以实现更复杂的远程认证方案[61]。

Enclave 可能使用不受信任的操作系统的服务,这些服务不需要访问普通敏感的 enclave 数据,例如文件或网络 I/O。对于这些情况,飞地可以利用属于 Sencl 的 Kcom 来保护其敏感数据。 CURE 还允许多个 enclave 通过操作系统共享加密的敏感数据。然而,假定所需的密钥交换是在服务提供商的后端执行的,因此超出了 CURE 的范围。

每个包含加密库的 enclave 也可以创建自己的密钥(Kcom 除外)并将其存储在 Sencl 中。因此,飞地还可以实施密钥轮换、撤销或恢复方案,但这是服务提供商的责任,因此超出了 CURE 的范围。

在每次 enclave 设置/拆卸以及上下文切换进出 enclave 时,SM 都会刷新所有核心独占的缓存资源,即数据缓存、TLB 和 BTB,从而防止跨执行上下文的信息泄漏。

User-space Enclaves

用户空间 enclave(图 2 中的 Encl1)包含一个完整的用户空间进程。

OS integration.

用户空间 enclave 的关键特征是它与操作系统的紧密集成,即它依赖操作系统进行内存管理、异常/中断处理以及通过系统调用(例如文件系统或网络 I/O)提供的其他服务。操作系统像普通用户空间进程一样调度用户空间飞地,只是进出飞地的上下文切换被 SM 拦截。所有用户空间飞地都使用操作系统的服务,从而防止代码重复。此外,用户空间飞地不包含管理软件,从而导致二进制文件更小。

Controlled side-channel defenses.

在受控侧通道攻击中,攻击者通过观察操作系统管理的资源(主要是页表)的使用情况来获取有关飞地执行状态的信息[65,92,101]。 CURE 通过将用户空间 enclave 的页表移至 enclave 内存来防御这些攻击。更微妙的受控侧通道攻击利用了飞地的中断处理由操作系统执行的事实[91]。 CURE 还允许每个飞地注册陷阱处理程序以观察其自己的中断行为,并在检测到可疑行为时采取相应行动,从而减轻这些攻击 [15, 79]。

Limitations & usage scenarios.

用户空间飞地无法运行更高权限的代码,例如设备驱动程序。因此,与外设共享的所有敏感数据都必须由不受信任的操作系统中的驱动程序处理,因此如果不加密,则不受保护。因此,用户空间 enclave 无法保护与传感器或 GPU 等设备交互的敏感服务。相反,用户空间飞地在保护依赖加密数据传输的短期服务(例如一次性密码 (OTP) 生成器、支付服务、数字密钥服务等)时非常有用。

Kernel-space Enclaves

内核空间 enclave 可以仅包含内核空间 (Encl2),也可以包含内核和用户空间 (Encl3)。

Providing OS services.

内核空间 enclave 的关键特征是它能够在特权 (PL2) 软件层甚至虚拟机管理程序级别 (PL1)(如果可用)的 CPU 内核上裸机运行代码。因此,操作系统服务,例如内存管理可以在 enclave 内部的运行时 (RT) 组件中实现(图 2)。这会导致与不受信任的操作系统共享更少的资源,因此更容易防范受控的旁道攻击[91,92,101]。此外,通过将设备驱动程序包含到 RT 中,可以建立到外设的安全通信通道。此外,内核空间 enclave 提供了更多的计算能力,因为 CURE 允许跨多个内核运行内核空间 enclave。在 CURE 中,外围设备可以在飞地设置时由 SM 专门分配给单个飞地,也可以在不同飞地之间共享和/或操作系统。当(重新)分配给新实体时,SM 会刷新外设的内部存储器,以防止信息泄露 [49,72,107]。

Protecting virtual machines.

CURE 将内核空间包含到 enclave 中的能力允许构建封装完整虚拟机 (VM) 的 enclave。 VM 不是独立的,而是依赖于虚拟机管理程序提供的内存和外设管理服务,这使得 VM enclave 容易受到受控侧通道攻击 [38, 51]。 CURE 通过将 VM 页表移至 enclave 内存并将未修改的完整驱动程序包含到 enclave 中以避免对不受信任的虚拟机管理程序的依赖来缓解此问题 [16, 17]。至于其他内核空间飞地,外设由 SM 临时分配给 VM 飞地。同样,在重新分配外设之前,SM 会清理其内部存储器。

Limitations & usage scenarios.

敏感服务可以移植到内核空间飞地而无需更改它们。然而,与用户空间 enclave 相比,需要添加 enclave RT,这会增加二进制大小、增加开发开销并增加内存消耗。此外,为 enclave 选择的 CPU 核心首先必须从挂起的进程中释放出来,与操作系统和在其上启动的 RT 分离。然而,当保护严重依赖外围通信的服务时,例如使用生物识别传感器的身份验证服务、通过传感器收集输入数据的 ML 服务或将计算卸载到加速器、DRM 服务或需要安全 I/O 的一般服务,则需要内核空间飞地。

Sub-space Enclaves

在 CURE 中,可以自由定义飞地信任边界,这允许构建细粒度的飞地,仅包含驻留在特权级别的软件部分,因此称为子空间飞地。

Shrinking the TCB

当在系统的最高特权级别 (PL0) 中构建时(图 2 中的 Encl4),子空间飞地尤其有吸引力。在 CURE 中,子空间飞地用于将 SM 与固件代码隔离,以防止固件代码中可能存在的可利用的内存损坏漏洞 [24]。此外,第 5.3 节中描述的硬件对策用于防止固件代码访问 SM 数据或硬件原语。最终,这最大限度地减少了 CURE 中的软件 TCB,而不是依赖于包含最高特权级别(即 EL3 (ARM) 或机器级别 (RISC-V))中所有代码的软件 TCB 的其他 TEE 架构,例如 TrustZone [3]、Sanctuary [10]、Sanctum [22]、Keystone [48]。

Hardware Security Primitives

在这里插入图片描述

Defining Enclave Execution Contexts (SP1)

Enclave ID registers
Propagating the enclave ID

Access Control on the Bus (SP2)

Enclave memory isolation
Assigning peripherals to enclaves
DMA protection

On-Demand Cache Partitioning (SP3)

Prototyping CURE on RISC-V

RISC-V System-on-Chip platform

Software stack

Cryptographic underpinnings

Software CURE Enclaves

Enclave Memory Layout

Security Monitor

User-space Enclave

Memory management
Syscalls

Kernel-space Enclaves

Allocating resources
Enclave-OS communication
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

粥粥粥少女的拧发条鸟

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值