以Intel SGX为例的可信执行环境。简单的基本原则。“你好,世界!”

本文主要针对的是只有

开始研究确保可执行程序代码信息安全的方法和方法。迟早,所有软件开发人员和系统工程师都将面临这样的任务,该任务发生在Altiriks Systems的一个项目中,在此框架内,有必要在无条件的无保护环境中实现程序代码的安全执行。为此,除了已经众所周知的描述信息保护的方法和手段之外,还选择了在俄罗斯项目中很少使用的技术可信执行环境(TEE),或者用俄语来说是可信执行环境的技术。在本文中,我们特别决定描述一个在可信代码执行环境(Intel Software Guard Extensions或SGX)中使用Intel处理器区域的实际示例。



给定制造商的处理器不仅支持受信任的运行时。而且,TEE受到许多AMD(安全执行环境,安全技术)处理器,ARM(TrustZone)处理器和RISC-V处理器的支持。此外,TEE受到现代IBM Z大型机的支持。我们选择Intel SGX作为示例,因为我们相信在撰写本文时(2020年夏季),Intel处理器是后苏联领域最受欢迎且可用于初学者的处理器。有关支持Intel SGX的Intel处理器型号的完整列表,请通过选择适当的技术来访问Intel产品规格(ARK)下的Intel网站。是的,也许可以将Intel SGX仿真用于教育或研究目的。处理其中一些仿真发现了设置它们的许多困难。您还需要了解,对于真正的“战斗”项目,当然不接受基于设备功能的技术仿真。



您的任何反馈,特别是来自已经在其项目中使用TEE的经验的专家的评论和补充,或者来自那些刚开始使用该技术的人员的问题,都将有助于在以下文章中更详细地公开此主题。提前致谢!



介绍



在探索受信任的运行时环境的过程中,我们首先提出的主要问题是:我们可以信任计算机系统的组件吗?如果可以,怎么办?开发人员,尤其是英特尔工程师,对这个问题给出了明确的答案:除了英特尔本身,没有人可以回答。这是什么意思?我建议更详细地了解这一点。



特权环



为了安全起见,将任何计算机的系统组件划分为特权级别。所有基于Intel处理器的现代系统都不仅具有特权环系统。从外部到内部,对于处理器当前正在处理的代码,其权限得到了扩展。





铃声号码3。外环包含我们日常生活中在计算机上使用的所有用户应用程序,它们具有最低的访问级别。

2号和1号环操作系统和设备驱动程序位于这些级别。

环号0。主管模式。这是操作系统内核(外围设备管理,进程之间的资源分配)以及系统驱动程序的所在地。

环号1。系统管理程序。如果多个操作系统同时在计算机上运行,​​则负责分配资源,并且还负责隔离它们。

环号2。系统管理模式(SMM-系统管理模式)。管理系统的电源,管理扩充卡。



我们可以形成越来越多的环来限制层次结构各个组件的功能,从而创建一个越来越复杂且负载越来越大的系统。但是,这只会使攻击者更容易:系统越复杂,越容易在其中找到漏洞。但是,如何在需要的地方提供额外的安全保护呢?答案是一个字。



飞地



攻击者的主要任务是获得特权级别,该特权级别将使攻击者能够访问必要的系统资源。如果这是受害者应用程序的机密,则恶意应用程序需要准确地负责将机密存储在系统中的访问级别。这表明了以下结论:应将应用程序秘密的管理委托给最内层的环,因为那里的访问是最困难的。但是,这种方法已被重新考虑。现在,所有机密与用户应用程序以及在一种情况下管理这些机密的代码都存储在同一级别:没有人,除了处理器,绝对没有人可以访问它们。程序和数据按原样打包到一个存储中,在这种情况下,此存储称为安全区(安全区-关闭,锁定),仅处理器拥有的密钥。





在可信环境下工作的应用程序



系统越简单,它包含的代码越少,基于安全漏洞打开它就越困难(我们不是在谈论根本不受保护的系统),我们得到了一定的公理:使用秘密的代码应尽可能简单和简短。将整个程序代码打包到一个安全区中是不切实际的,因此,使用安全区的应用程序应分为两部分:“可信”和“不可信”。受信任的一个存储飞地(可能有几个),而不受信任的一个存储主程序代码。



可信部分是称为ECALL(安全区调用)的一组功能和过程。此类函数的签名必须写在特殊的头文件中,而其实现则在源代码文件中。通常,该方法类似于我们通常在头文件中使用的方法,但是在这种情况下,使用了一种特殊的类C语言EDL(安全区定义语言)。还需要编写可以在安全区域内调用的那些函数的原型,这些函数称为OCALL(外部调用)。原型写在与ECALL函数相同的标头中,并且与ECALL不同,实现被相应地写在应用程序的不受信任部分中。

使用Diffie-Hellman协议通过认证将可信和不可信代码紧密结合在一起。处理器负责签名过程,在该过程中存储了信息交换密钥,该密钥在每次重新引导系统时都会更新。隔离区的内容存储在用户应用程序使用的共享内存中,但是存储是加密的。只有处理器可以解密内容。在理想的世界中,安全区域代码的编写没有任何错误,并且所有硬件都完全按照制造商的意图工作,而没有别的,我们将获得一个通用的,完全安全的系统。该系统的主要优点是在执行所有其他程序(包括用户程序)的同一处理器上执行秘密部分。



但是,在过去的几年中,现代处理器的大量微体系结构漏洞已经出现在广大读者面前,从而可以访问飞地内部:Foreshadow(Spectre类漏洞),SGAxe,Zombieload,CacheOut等。不保证此列表不会补充另一个严重的硬件漏洞,该漏洞的软件修复不能称为软件“补丁”。也许我们将活着看到向世界展示一种全新的处理器体系结构的时代,在这个时代中所有缺点都将得到纠正,但是就目前而言,值得一提的是我们所拥有的。而且,我们手边有一个功能强大的多功能工具,可以极大地提高当今系统的安全性。提高很多它在全球数十亿种设备中以一种解释或另一种解释来实现:从智能手表,智能手机到大型计算集群。



你好,世界!



让我们从理论转向实践。让我们编写一个实现已完成的标准任务的小程序:打印字符串“ Hello world!”。在这种解释中,我们还将指出发送消息的位置。



首先,您需要从官方网站下载并安装SDK以与SGX一起使用。要下载,您需要完成一个简单的注册过程。在安装阶段,将要求您将开发包集成到计算机上可用的VS版本中,执行此操作。为使用SGX成功实施第一个项目做好了一切准备。





启动VS并创建一个Intel SGX项目。





我们为项目和解决方案选择一个名称,然后等待“下一步”。



接下来,将提示您选择一个项目配置,不要更改任何内容,保留最初建议的值。







然后将另一个项目添加到创建的解决方案中:一个常规的C ++控制台应用程序。

因此,以下图片应出现在项目对话框中:







然后,您需要将飞地链接到不受信任的部分。右键单击“不受信任的部分”项目。







接下来,您需要更改项目的某些属性。



图片






必须执行此操作,程序才能正常工作。我们对两个项目都重复上述步骤。



还必须在解决方案的属性中指示主要项目。





就是这样,我们的程序已准备好实施。



该程序将包含3个文件供我们使用:Enclave.edl(相同的标头),Enclave.cpp(详细说明了ECALL的实现),Untrusted Part.cpp(主项目文件是不受信任的部分)。让我们将



以下代码放入文件中:



Untusted Part.cpp:



#define ENCLAVE_FILE "Enclave.signed.dll" //,     

#include "sgx_urts.h" // ,           
#include "Enclave_u.h" //   
#include "stdio.h"

void print_string(char* buf) //OCALL     -   
{
	printf("ocall output: %s\n", buf);
}

int main()
{
	sgx_enclave_id_t eid; // id ,      ,    id
	sgx_status_t ret = SGX_SUCCESS; //        
	sgx_launch_token_t token = { 0 }; //    
	int updated = 0; //      
	const int BUF_LEN = 30; //  ,     

	ret = sgx_create_enclave(ENCLAVE_FILE, SGX_DEBUG_FLAG, &token, &updated, &eid, NULL); //  

	if (ret != SGX_SUCCESS)
	{
		printf("Failed to create enclave with error number: %#x\n", ret); //  
		return 0;
	}
	char buf[BUF_LEN]; //  ,      

	enclaveChat(eid, buf, BUF_LEN); // ECALL  

	printf("\noutput form main(): %s\n", buf); //  
}


Enclave.edl:



enclave {
    from "sgx_tstdc.edl" import *;

    trusted {
        /* define ECALLs here. */
        public void enclaveChat([out, size=len] char* str, size_t len);
        /*   ,    . OUT -   ,   
                , out     .
           ,          ,
                 .
        */
    };

    untrusted {
        /* define OCALLs here. */
        void print_string([in, string] char* buf); //  ,     
    };
};


Enclave.cpp:



#include "Enclave_t.h"

#include "sgx_trts.h"
#include <cstring>

void enclaveChat(char* str, size_t len)
{
	char* secret = "Hello from better place"; //   

	memcpy(str, secret, len); //   ,  

	print_string(secret); // OCALL-  
}


按f7键-构建解决方案,然后按ctrl + f5键运行。



如果收到这样的错误:





确保在BIOS中启用了Intel SGX:BIOS:安全性/ IntelSGX / Enabled。



如果没有错误,在控制台屏幕的前面,您会看到以下几行:





…恭喜,您的第一个采用Intel SGX技术的程序已准备就绪。我希望代码中的注释对理解有所帮助,否则,您随时可以在注释或私人消息中提出问题。



All Articles