深入了解ARM系统的安全处理

打印 上一主题 下一主题

主题 1763|帖子 1763|积分 5289


上图是一个典型的ARM SoC内部结构,在这个结构里,Trustzone做的事情是保护数据在芯片内部的安全,不允许非授权的访问,哪怕这个访问来自CPU。初看有些复杂,不过我们可以拆开逐步分析,从硬件角度开始比软件更清晰。
起首,按照Trustzone的划分,一个芯片内被划分为安全世界和非安全世界。上图中,中间黑色的部分是总线,总线上面是主装备,下面是从装备(主装备中的缓存是例外,这个以后说)。读写哀求总是从主装备发往从装备的。
作为从装备,区分它是不是属于安全世界相对简单。如果一个从装备不存在成块的空间映射,好比I2C或者PWM,那么我只要在总线访问它的时候,额外的加入一个管脚(取名为PROT),就可以告诉它本次访问是不是来自安全世界。如果从装备本身是完全属于被保护的安全世界,不接受非安全的访问,那么只要简单的拒绝,返回错误或者无意义数据即可。同样,如果从装备本身处于非安全世界,那么对于安全和非安全访问,都可以返回正确数据。另有,从装备所处于的世界,是可以动态设置的,且动态设置本身必要处在安全世界,这个以后讨论。
对于块装备,包罗闪存,sram和内存等,它们的某些地址块必要处于安全世界,其他的处于非安全世界。为了实现这一点,就必要在它们前面插入一个检验模块(比方图中左方,DDR上面的TZC400),来判断某个地址是不是能被访问。当地址被送到这个检验模块,模块会联合PROT管脚去查表,看看本次访问是不是被允许,然后做相应步伐。表本身和之前的动态设置一样,必须是在安全世界里面设置的。
至此,从装备就分析完了,是不是感觉特别简单?另有些细节,在把主装备也讲完后,我们会从系统角度来关注。
对于一般主装备,不思量自带的缓存时,实在和从装备也差不多,也分为安全和非安全,可以在安全世界动态设置。设置完成后,这些主装备会按照本身所处的世界,驱动PROT管脚和地址来访问从装备,得到相应返回。不过这里的一般主装备不包罗中断控制器,系统MMU,调试模块和处理器,接下来对这些例外模块进行具体分析。

 起首是处理器。在上图情况,接了CCI总线后,处理器接在缓存一致性端口ACE上(不明白的请参考从前的文章),它的缓存是可以被别人访问的,并且这个访问,是从主装备到主装备(当然,在处理器内部是从端口),不会经过总线送到内存,也不会经过检验模块TZC400。这时就有个毛病,通过利用一个非安全世界的模块,好比上图的橙色主装备,假装去读一个被安全世界保护的内存地址。这个地址本来存在于内存,被TZC400保护,但是由于总线的监听功能,读哀求有可能被发往处理器缓存,从而绕过保护。为了防止这种情况,处理器在所有的页表和缓存都做了特殊计划,加了一个标志位,标志本缓存行是否属于安全世界。如果别的非安全世界主装备来监听安全世界缓存行,由于安全位差别,处理器会认为这是两个差别地址,哪怕它们的地址一致,返回缓存未命中。如许,就不会把数据走漏。有人会问,这个标志位来源于页表,改了页表中的这一位不就可以访问了?实在不行。因为安全世界页表位于被保护的内存区域或者缓存,就算破解了利用系统也无法访问。又有人会说,那改了非安全世界的页表中安全位,并伪造一个安全世界的地址,岂不是可以让CPU模拟出一个访问安全世界的传输,送到总线和TZC400?TZC400或者对端缓存一看地址和PROT管脚都是符合要求的,应该就会返回保密数据吧?想法是不错,但是当CPU位于非安全世界时,它会忽略页表中的安全位,所以不可能发出PROT为安全的传输。所以,我们可以对这点放心。
以上是别的主装备访问处理器,那如果处理器本身处于非安全世界,有没有可能访问其他主装备的安全缓存?当然有。所以不要把其他主装备接到ACE端口,以免被监听,一般主装备是不会做缓存上的安全与非安全区分的。接到ACE-Lite接口无所谓,反正计划上就无法被读取缓存数据。除此之外,还存在一个例外,就是GPU。在最新的ARM G71图形处理器上,是支持双向硬件一致性的。也就是说,GPU也可以被监听缓存的。为了简化计划,图形处理器被设成永世处于非安全世界,CPU尽管读,不在乎,它使用别的一种机制来保护数据,以后介绍。
对处理器缓存熟悉的人可能会想到用跨缓存行的非安全变量来访问被保护的数据。没用的,处理器计划者早就想到这点,要不就黑白对齐访问非常(包含exclusive access的时候),要不就不会给你数据,具体到每个处理器有所差别。
另有一个毛病没堵上,那就是缓存维护,TLB和分支猜测利用。ACE端口包含了DVM利用来维护它们,安全性如何保障?同样的,地址中也有安全和非安全位。不过话说回来,DVM利用无非就是无效化某些缓存,分支猜测和TLB项,不存在安全数据被读取,TLB被篡改的情况。
到这里可能你会觉得有点晕,不少毛病必要堵。我们可以回顾一下,必要记住的是各种缓存利用,通过安全标志位保护,避免毛病。对比处理器计划者所要思量的情况,这点毛病不值一提。
杜绝了缓存毛病后,另有别的隐患,好比仿真器。调试模块可以被用来访问各个从装备,也可以访问和影响处理器内部资源。从装备侧的防护很容易,把调试模块当成一般的主装备处理就行。处理器内部的寄存器,缓存等资源,必要处理器从计划开始,就要为所有资源定义安全级别。被保护的资源对于来自调试模块的未授权访问会被禁止。只有通过安全启动链,安全世界的软件才气打开寄存器SDER,从而允许外部仿真器影响被保护的安全世界资源和处理器运行状态,访问被保护的资源。
那处理器内部的资源是怎么划分的?以ARMv8举例,如下图:

这幅图相信许多人都看到过。ARMv8的处理器被分成四个特权等级,通常EL0跑用户态步伐,EL1内核,EL2假造机。EL0-1分为安全与非安全,EL3只有安全世界,EL2不区分,两个世界的切换必须经过EL3。我们谈到的处理器内部资源,包罗寄存器,缓存,非常,MMU,许多都会分组,组之间看不到或者低级不可访问高级,从而保证安全。没有分组的,好比通用寄存器,就必要软件来维护,防止非安全世界的看到安全世界的数据。
引起安全切换的会有几种可能:中断和SMC指令。中断分为如下几种情况:

 
非安全世界下,在EL1或者EL0,当一个非安全中断到临,那么系统没必要切换安全状态,作为一般中断处理,切到EL1即可。
非安全世界下,在EL1或者EL0,当一个安全中断到临,那么系统必须先切到EL3,不然就没法做安全世界切换。
安全世界下,在EL1或者EL0,当一个安全中断到临,没必要做安全世界切换,作为一般中断处理,切到EL1即可。
安全世界下,在EL1或者EL0,当一个非安全中断到临,那么系统必须先切到EL3,不然就没法做安全世界切换。
当跳到EL3的Secure Monitor步伐处理上下文切换时,IRQ/FIQ中断屏蔽位不起作用,哪怕打开了也不会触发,直到Secure Monitor处理完,向下跳到相应的安全世界EL1时,才会让原来的中断屏蔽规复,从而触发中断。此时处理中断的是安全世界的中断步伐,处于被保护的内存区域,杜绝非安全世界的步伐篡改。
那怎样触发安全与非安全中断呢?这在中断控制器里有定义,早年的定义中只有FIQ可以作为安全中断,后期的可设置,并且,相应的安全世界设置寄存器只有在处理器的安全世界中才可以访问。
SMC指令和中断触发雷同,只不过软件就可以触发,切换到Secure Monitor。这里,非安全软件可以提出触发哀求,在通用寄存器填入参数,却无法控制安全世界的处理步伐做什么,也依然看不到被保护内存数据。所以防止数据泄密的使命就靠安全利用系统了。
至此,安全启动后的基本硬件防护已经完成,但如果你以为这就是Trustzone,那就错了,出色的在后面。
我们可以把Trustzone放到实际应用里面看看是不是可行。以DRM举例,如下图:

 在播放授权视频的时候,视频流来自网络或者闪存,它们不必要在安全世界,因为数据本身就是加密过的。然后被解密并放到被保护内存,等待解码。上图中,暗码保护和解密是通过安全硬件模块Crypto来完成的,这个我们以后再分析,先处明白密完成后的视频流。此时有两种方案:
第一种,非常自然的,可以把所有的过程在安全世界完成,那么图形处理器,视频处理器和体现模块必须都工作在安全世界,能访问安全世界的数据,才气完成工作。可如许就带来一个问题,那就是驱动。我们知道,图形处理器的驱动黑白常复杂的,并且手机上只存在Linux和windows下的图形驱动,和OpenGL ES/DirectX配合。而安全世界的利用系统(TEE,Trusted Execution Environment)是完全不兼容的安全系统,甚至有的都不支持SMP, 完全不存在可能性把图形驱动移植上去,也没有任何意义。如许的话,就只能把图形处理器从流程中挖掉,只留下相对简单也不必要生态的视频和体现模块的驱动,工作在安全世界,而GPU的输出送到体现模块,由体现模块进行混合。这是一种可行的方案,也确实有公司这么做。但是从久远看,图形处理器总是会参与到这个过程的,别的不说,只说VR和AR流行以后,要是假造个体现屏出来,上面播放视频,然后放在一个假造出的房间,那他们之间肯定是要进行互动的,此时体现模块就必要把视频图层送回GPU进行运算。如果GPU不在安全世界,那就会造成泄密。
TZMP1

为了办理上述问题,有了第二种办理方案,称作TZMP1(Trustzone Media Protection 1),引入了保护世界的概念。保护世界工作于非安全世界,如许才气兼容图形驱动。那安全怎么办?它必要添加四根管脚NSAID,雷同于安全世界的PROT信号,只不过做了更细的划分,使得GPU/视频/体现模块要访问被保护内存时,预先定义好了权限。而这个权限的设置,也是通过前文的TZC400来实现的,在安全启动链中就完成。CPU的权限通常是0,也就是最低。而体现控制器权限是只读。
如许一来,我们之前的老问题,恶意缓存监听,又回来了。在新的A73和G71加CCI500/550总线系统里,可以支持双向硬件一致性。这意味着GPU也能被监听。这下各人都在非安全世界,缓存里的安全位不起作用,怎么办理?这必要总线的配合。ARM的总线CCI500/550,有一个保护模式,打开后,不光支持上文的NSAID管脚,还可以在监听的时候,把监听传输替换成缓存行无效化命令,直接让目的把相应缓存行无效化。如许一来,数据还是必要从内存读取,保证安全。并且这个过程对软件透明,无需做任何改动。但是此时,辛辛苦苦计划的硬件一致性就完全起不到加速作用了,性能受到影响。好在运行OpenGL ES的时候,GPU是不会发出共享传输的,CPU也不会没事去监听GPU的数据。而下一代的图形接口Vulkan,会开始使用GPU双向一致性,那时候会有影响。另有一点倒霉的是,如果同时运行OpenCL和DRM,OpenCL也用不上双向硬件一致性,必须重启系统切换到非保护模式才行。
以上两种方案同时也可用于安全支付,只要把密钥和指纹放在安全内存里,让体现模块单独读取一个安全图层就行。此时,安全图层的数据不可能被处理器上的恶意步伐读到,无论体现模块是在安全世界还是保护世界。
在实际使用中,现有的TZC400作为内存保护模块,有几个致命的缺陷。第一,它的设置只能在启动时完成,无法动态改变,也就是说,一旦某块内存给了安全世界,就无法再被非安全世界的利用系统使用,哪怕它是空闲的。在4K视频播放时,往往必要分配几百兆内存,还不止一块。如果一直被占着,这对于4GB内存手机来说是个沉重的负担。怎么办理?只能改成动态设置的硬件。
改成动态后,还会碰到第二个问题。TZC400和它的改进版最多只能支持最小颗粒度为2MB的内存块管理。为什么不弄细些呢?很简单,如果设成4KB,和系统页大小一致,那么4GB的物理内存就必要一百万条目来管理。如果做成片上内存,比二级缓存还大,不实际。而做内存映射,就和MMU一样了,经过CPU的MMU后,数据访问还要再穿越一次MMU,延迟显然大。别的,这一层的MMU无法使用一二级缓存放页表,服从极低。如果继续保持2MB的颗粒,那么Linux在分配内存的时候,很难找到连续的2M物理块,因为他必要512块连续4K物理页来拼接。如许,我们很容易就分配失败。这就是TZMP2V1。
再有一个问题,就是安全世界TEE和非安全世界REE的切换性能。由于安全切换扳连到上下文的保存,通常它所必要的时间是毫秒级的。在DRM中,由于每一帧都必要进入到TEE来进行密钥利用,每秒钟必要进行几十次切换,累积起来就是一个可观的数字。怎么避免?有一个办法,就是使用一个额外的硬件,在ARM的方案里被称作CryptoCell。它可以接受非安全利用系统世界来的命令,在本身的硬件里实行暗码利用。整个过程中不会把安全数据区暴露给CPU,只是把利用结果放在指定非安全内存。如许,CPU就不必进行安全世界上下文切换,只是必要休眠或者轮询结果就可以。当然CryptoCell另有许多其他功能,安全启动,密钥管理,全盘加密时候会用上。

TZMP2V2

既然TZMP2V1有这么多问题,第三种基于假造机的方案就出现了。不过这个方案基本上推翻了Trustzone最初的计划意图,我们来看下图:

 在这里,作为内存保护的TZC400完全移除,而系统MMU加了进来。内存保护怎么做?靠物理地址重映射。先看处理器。在启动链中,从EL3向EL2跳的过程时,就定义好保护内存,并且EL2,也就是假造机的页表存放于保护内存,EL1的安全页也同样放在保护内存。如许,当处理器进入到EL1,哪怕通过篡改EL1非安全页表的安全位,也终极会被映射到它所不能访问的安全内存,从而起到保护作用。同样的,给处于非安全世界的控制器也加上系统MMU,让装备假造化,同样可以控制安全。这就是TZMP2V2。有了系统MMU,页表可以做成4KB大小了,也不用担心CPU那里穿越两次MMU。这时候,也不用担心恶意监听缓存,因为所有穿过二级MMU的访问里,安全位都是经过检验的的。
但是,不看别的,光是为装备加入这些系统MMU,就会增长许多面积。另有,光加MMU
不够,还要加入系统的三级甚至四级缓存,才气让MMU服从更高,不然延迟太大。当然,如果装备使用的页表并不许多,可以对MMU简化,好比增大最小颗粒度,减少映射范围,直接使用片内内存。这必要系统计划者来做平衡。对于GPU来说,要支持双向一致性,还得思量让监听传输通过MMU,不然功能就出问题了。所以,ARM在2016年所定义的TZMP2方案,本质上还是TZMP2V1。TZMP2V2必要到2018年后才有可能出现。
那现在作为过渡方案,应该怎么办呢?可以使用TZMP2v1,然后牺牲一点面积,在雷同TAC400的内存访问过滤器上,实现64KB的颗粒度,如许4G空间只必要256K条目就可以实现全映射,并使得查表的延迟保持在1ns左右。每一条目2-4bit属性位,总体64-128KB大小,。在分配物理内存时,使用差别优先级,尽量低落分配64KB内存失败的概率。
如果终极使用了TZMP2V2,那么假造化就酿成了一个切实需求。然后会发现,ARM的中断和装备的假造化还不完善。接下来我从硬件角度表明下假造化。
系统MMU

说到假造化,先要表明系统MMU。

如上图所示,系统MMU实在很简单,就是个二层地址转换。第一层,虚地址到实地址,第二层,实地址到物理地址。请注意,没有第二层转换时,实地址等同于物理地址。这个模块既可以两层都打开,也可以只开一层,看情况而定。
上图比较清晰的体现了一层映射的过程。其中,装备发出的虚地址哀求,会先经过TLB,它里面存了从前访问过的页表项,如果有,就直接返回,没有就往下走到第二步table walk。第二步里,MMU会按照预设的多级基址寄存器,一级级访问到终极页表。如果MMU位于CPU内,那table walk过程中每次访问的基址和表项,都可以存放于缓存中,大大进步服从。如果在装备上,只有内建的TLB表项,后面没有缓存,那未命中TLB的都是访问DDR,服从自然降落。所以CPU和GPU等经常访存的装备,都是自带第一层MMU和缓存。而对于没有内部MMU,切换页表又不是很频繁的装备,好比DMA控制器,可以在下面挂第一层MMU,此时驱动就简单了,直接把应用步伐看到的虚地址给DMA的寄存器就行,MMU会本身按照基地址去查找相应页表并翻译,把实地址送到总线。不然,驱动还要本身查找实地址再写入寄存器。
TZMP2v2

我们前面说过,在TZMP1和TZMP2v1中,内存保护是靠TZC400来完成的。而到了TZMP2v2,取消了TZC400,这时靠假造化的二层地址映射。二层映射的过程和一层映射基本一样,不再详述,但是性能问题会被放大。假设在一层中,经过四级基址查到终极页,而在二层中,这每一级的基址查找,又会引入新的四级基址访问。所以至少要经过4x4+4=20次访存,才气确定物理地址。如果没有缓存的资助,服从会非常低。其他可行的办法是减少基址级数,好比linux只用了三级页表,但纵然如此,也必要3x3+3=12次查找。在包含缓存的ARM CPU上,假造机的服从可以做到80%以上。而二层MMU应用于装备实现装备假造化的时候,就必要警惕计划了。
假造化

有了系统MMU,我们就有了全芯片假造化的底子。那在对系统性能和本钱做完平衡,采取合适的系统MMU计划之后,是不是就可以实现假造化,并且靠假造化实现安全了?没那么容易,另有别的问题必要思量。
假造化脱胎于仿真器,就是在一个平台上模拟出另一个平台。在指令集雷同的时候,没有必要翻译每一条指令,可以让指令直接被硬件实行,如许指令的服从算是得到了办理。当然,对于某些特殊指令和寄存器访问,还是必要hypervisor处理的。接着第二个问题,访存。我们前面表明过,对CPU来说,高效的假造化访存,就是让指令高效的经过两层翻译,而不是每次访存都必要触发假造机EL2的非常,切到Hypervisor,再得到终极物理地址。这一点在没有缺页非常的时候,ARM的假造化也已经做到了,而有缺页非常时还是必要Hypervisor处理。再接着是装备访存假造化,有了系统MMU,也可以高效做到。再就是处理器和装备中断假造化,如下图:

 最高效的假造中断处理,是GuestOS直接接受本身的假造终端,而不必跳转到Hypervisor再回来。这就必要GICv4之后的中断协议,之前的还都不支持。实现上,必须要求中断控制器能支持多个假造中断号和假造装备号,否则没法正确的发送中断哀求。而要支持这一特性,又必要把描述符放在内存,而不是控制器的内部寄存器,否则片上内存放不下。这又进一步引入了延迟。另有,设置中断处理跳转的寄存器不应该被GuestOS访问,否则会有安全隐患。做系统计划时必须综合思量这些因素。
高效的指令,访存和中断形成了高效的假造机。在实际应用中,这类驱动被称作pass-through device,穿透式装备,是最高效的一种。其余的方式,另有完全假造化装备(无需改驱动但服从最低)和半假造化装备(必要特殊驱动和Hypervisor沟通)。在网络应用中,如果是跑数据面转发,必须使用穿透模式。据我所知,思科开放的VPP(Vector Packet Processing)可以在Intel服务器上做到90%以上的非假造化性能,并且可以线性提升多和性能。这靠得是把上文所有的假造化特性全部用上,外加Stashing等总线传输技术才气做到。而在ARM平台,支持GICv4的IP得等到2018年才有,做成高效的假造机并配上AMBA5的总线,处理器,外加成熟的软件,估计得2020年,和Intel还是有不小的差距。
ARMv8-R Trustzone

这里可以顺便介绍下ARMv8-R Trustzone,前面我们说过,它使用了汽车上的假造化来做安全,并且保证了实时性。在正常的假造化上,由于存在两个阶段的地址转换,涉及到几十次的访存,延迟大是其次,关键是无法保证确定的访问时间。这在汽车应用上是不可接受的。怎么办?非常简单,第一,去掉虚实转换,各人看到的都是一个物理地址空间,进步服从。第二,只提供二个阶段的地址查抄(分别属于应用和假造机),并限定查抄的表项个数,好比16条,那么就不必要去内存里查找,直接命中片上内存。在中断处理上,减少假造中断号和装备号的数量,避免访存。几个步伐加起来,就能继续保证确定的较短延迟。当然,ARMv8-R Trustzone本身实在是支持虚地址的,只不过会引入一些延迟,这就必要系统计划者做权衡了。有了ARMv8-R Trustzone的隔离,就可以在同一个芯片上跑差别的利用系统和第三方应用,而不必担心安全问题。在汽车上,之前的应用是AUTOSAR,假造化要代替它,另有很长的路要走。好在汽车芯片商,好比瑞萨和NXP,对这一厘革非常积极,已经开始芯片的计划了。
ARMv8-M Trustzone

再来说说ARMv8-M Trustzone。事实上,在2016年前,是不存在Cortex-M上的Trustzone的。许多号称实现了Turstzone的MCU,只是借用了这个概念,实在在安全计划上是有问题的。

在上图中,使用了ARM的核Cortex-M3和硬件安全IP CryptoCell,APB总线做了PROT位,还在SRAM/Flash和其他所有控制器上加入了地址安全查抄,并启用了安全启动链。如许就是符合Trustzone的系统了吗?答案是否定的。这个系统有个致命弱点,如果第三方步伐恶意访问秘密数据,由于MCU无法区分安全和非安全状态,导致给总线的信号无法实时驱动PROT管脚,从而从装备无法判断到底是不是安全访问。当然,也可以通过软件来拉PROT信号,但是所有步伐都是在一个状态下,看到的寄存器都是一致的,恶意步伐也能驱动PROT管脚,保护步伐就失去了意义。
 那难道必须使用ARMv8-M核才气在MCU上做Trustzone吗?也不是。如果在上述系统中,再加一个M3,把它的PROT管脚拉成非安全状态,并把原来M3的PROT管脚拉成安全状态就可以了。第三方应用跑在非安全核,安全应用跑在安全核,他们之间通过硬件mailbox做通讯。并且由于不存在数据缓存,总线也不支持Snooping,也就不存在上文的缓存一致性安全问题。
那真正的ARMv8-M Trustzone是什么样的?如下图:

这里使用了新的M33核,它内部可以区分安全状态,所以就不必要两个核。并且AHB5总线本身就支持PROT管脚,配合CryptoCell IP,就可以实现雷同A系列的安全启动和访问了。在M33上,除了实时性之外,还必要把安全部分的硬件尽量做小,否则MCU面积本钱太高,不会有人使用。ARM使用了额外的硬件逻辑来资助定义安全,如下图所示,必要计划者本身顶一个很小的硬件映射表Arbitration Unit,来定义哪些区域是安全的。如许牺牲了灵活性,却省了面积。同时由于没有缓存,也不必要缓存中加入额外的面积资助判断。

安全启动 

最后,再阐述一下安全启动机制。之前的Trustzone的工作,都是在保证运行时不被恶意步伐窃取安全数据。那如何保证系统从启动开始,所有的系统软件都没有被恶意篡改?前面我们提到过芯片制造过程中,用熔丝fuse实现一些特殊的比特位,这些熔丝一旦被写入,就再也无法更改。这一机制可以被用来写入公钥。当然,由于熔丝的本钱较高,我们可以只写入公钥的哈希值,而把公钥存于芯片内部的Rom或者片外闪存。启动的时候,熔丝里哈希后的公钥,可以和片外的公钥做对比,确保哈希值未被篡改。然后,再使用这个公钥,去验证所有的启动代码的署名。如果有些启动代码本身必要保密,不被人读懂,可以用对称加密算法加密后,再对对称算法的密钥做署名和验证。如许一直启动到EL3,就可以建立信任链,为Trustzone打下底子。
不过还是有个问题没办理,那就是如何防止装备本身的身份验证问题。如果服务端必要确认某个装备是不是一个可信任节点,就必要装备用非对称算法的私钥对特征字段进行署名,然后发送到服务端。这个过程有可能被物理攻击,从而泄露私钥,芯片本身也有可能被磨片,造成私钥泄露。这时,可以用闪存的RPMB分区保护数据存储,用全盘加密保护传输,或者干脆把私钥存于别的的装备,从需求和本钱告竣一个平衡。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

惊雷无声

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表