代码角度理解SGX的认证机制(一):本地认证
一、基本概念
1、认证(attestation): 是指一个enlave中的程序向其他enclave证明其完整性和真实性的过程。intel SGX认证即是一个在SGX平台上运行的ISV enclave(证明者)希望来向远程enclave(验证者)证明其身份(MRENCLAVE)、和确实是在真实的SGX处理器上正确的隔离执行。
1)本地认证:同一个平台上的两个不同enclave之间认证
2)远程认证:enclave所属平台外的软件验证其真实性
2、MRENCLAVE 和 MRSIGNER:intel SGX为每一个enclave提供的两个度量值,分别为MRENCLAVE 和 MRSIGNER;
1)MRENCLAVE :Enclave Identity
其值为sha256的摘要结果;
sha256的内容包括:从enclave构建开始到初始化完成(EINIT指令执行后)之间的活动记录日志。
日志包含如下信息:
the code, data, and stack placed inside the enclave
the order and position in which the enclave’s pages were placed
the security properties of each page.
以上内容的任一更改都会导致hash结果不同,即MRENCLAVE不同,不同的enclave,该值不同
可以使用如下命令获取到mrenclave:
sgx_sign dump -enclave enclave.signed.so -dumpfile out.log
例如:本地证明demo中,sgx_sign dump -enclave libenclave_initiator.signed.so -dumpfile out.log
在out.log文件中的 metadata->enclave_css.body.enclave_hash.m字段就是MRENCLAVE值。
2)MRSIGNER:- Sealing Identity
enclave构建时使用的RSA签名的公钥的hash结果。签名的rsa密钥对相同,该值即相同。
同样在out.log中搜索mrsigner->value可以看到MRSIGNER。
3、TCB :Trusted computing base
4、EREPORT: 调用enclave时,创建的一个带有cmac签名的结构。包含enclave的两个标识符,enclave相关属性(boby中的attributes字段),硬件TCB的可信度等,及这些消息的MAC结果.(密钥由EGETKEY导出:)
5、EGETKEY:该指令根据调用enclave的属性和请求的密钥类型来产生用于不同目的的五种对称密钥。其中两种用于所有区域的sealing 和report keys。剩下三个仅限于SGX体系结构使用。
可参考此篇论文详细了解EGETKEY:
https://www.idc.ac.il/en/schools/cs/research/Documents/jackson-msc-thesis.pdf
6、Report Key:只有负责验证的enclave可以通过EREPORT 指令恢复Report Key。验证对端的report中的MAC值是否正确。双方只要在driver key的时候设置的参数一致,即可生成相同的mac key。
二、认证关键过程
本端用对端的target info,双方DH公钥的hash值及一些系统信息,生成report,该report带有一个MAC值。对端拿到这个report之后,通过EGETKEY指令获取Report Key,来验证MAC值是否和对端发送的一致。
首先,report.body的组成如下(可查看SIM代码):
typedef struct _report_body_t
{sgx_cpu_svn_t cpu_svn; /* ( 0) Security Version of the CPU */sgx_misc_select_t misc_select; /* ( 16) Which fields defined in SSA.MISC */uint8_t reserved1[SGX_REPORT_BODY_RESERVED1_BYTES]; /* ( 20) */sgx_isvext_prod_id_t isv_ext_prod_id;/* ( 32) ISV assigned Extended Product ID */sgx_attributes_t attributes; /* ( 48) Any special Capabilities the Enclave possess */sgx_measurement_t mr_enclave; /* ( 64) The value of the enclave's ENCLAVE measurement */uint8_t reserved2[SGX_REPORT_BODY_RESERVED2_BYTES]; /* ( 96) */sgx_measurement_t mr_signer; /* (128) The value of the enclave's SIGNER measurement */uint8_t reserved3[SGX_REPORT_BODY_RESERVED3_BYTES]; /* (160) */sgx_config_id_t config_id; /* (192) CONFIGID */sgx_prod_id_t isv_prod_id; /* (256) Product ID of the Enclave */sgx_isv_svn_t isv_svn; /* (258) Security Version of the Enclave */sgx_config_svn_t config_svn; /* (260) CONFIGSVN */uint8_t reserved4[SGX_REPORT_BODY_RESERVED4_BYTES]; /* (262) */sgx_isvfamily_id_t isv_family_id; /* (304) ISV assigned Family ID */sgx_report_data_t report_data; /* (320) Data provided by the user */
} sgx_report_body_t;
// assemble REPORT Datamemset(&tmp_report, 0, sizeof(tmp_report));memcpy(&tmp_report.body.cpu_svn,&(g_global_data_sim.cpusvn_sim),sizeof(sgx_cpu_svn_t));tmp_report.body.isv_prod_id = cur_secs->isv_prod_id;tmp_report.body.isv_svn = cur_secs->isv_svn;memcpy(&tmp_report.body.attributes, &cur_secs->attributes, sizeof(sgx_attributes_t));memcpy(&tmp_report.body.report_data, rd, sizeof(sgx_report_data_t));memcpy(&tmp_report.body.mr_enclave, &cur_secs->mr_enclave, sizeof(sgx_measurement_t));memcpy(&tmp_report.body.mr_signer, &cur_secs->mr_signer, sizeof(sgx_measurement_t));memcpy(&tmp_report.key_id, get_base_key(SGX_KEYSELECT_REPORT), sizeof(sgx_key_id_t)/2);
MAC生成的关键是对称密钥report key的导出:
需要素材如下:
/* Derive data for report key */
typedef struct {uint16_t key_name; /* should always be 'SGX_KEYSELECT_REPORT' */sgx_attributes_t attributes; /* attributes from SECS */se_owner_epoch_t csr_owner_epoch;sgx_measurement_t mrenclave;sgx_cpu_svn_t cpu_svn; /* CPUSVN from CPUSVN register */sgx_key_id_t key_id; /* KEYID from KEYREQUEST */
} dd_report_key_t;
// derive the report keyderivation_data_t dd;memset(&dd, 0, sizeof(dd));dd.size = sizeof(dd_report_key_t);dd.key_name = SGX_KEYSELECT_REPORT;memcpy(&dd.ddrk.mrenclave, &ti->mr_enclave, sizeof(sgx_measurement_t));memcpy(&dd.ddrk.attributes, &ti->attributes, sizeof(sgx_attributes_t));memcpy(dd.ddrk.csr_owner_epoch, SIMU_OWNER_EPOCH_MSR, sizeof(se_owner_epoch_t));memcpy(&dd.ddrk.cpu_svn,&(g_global_data_sim.cpusvn_sim),sizeof(sgx_cpu_svn_t));memcpy(&dd.ddrk.key_id, &tmp_report.key_id, sizeof(sgx_key_id_t));
ti 为target info,可以看出,用到了对端的mrenclave和attribute。
derive key函数如下:
// Compute the CMAC of derivation data with corresponding base key
// and save it to `okey'.
void derive_key(const derivation_data_t* dd, sgx_key_128bit_t okey)
{sgx_rijndael128_cmac_msg((const sgx_cmac_128bit_key_t*)(get_base_key(dd->key_name)),dd->ddbuf, dd->size, (sgx_cmac_128bit_tag_t*)okey);
}
get_base_key 函数是由系统生成,此处为SIM代码,所以为固定值:
const uint8_t* get_base_key(uint16_t key_name)
{switch (key_name) {case SGX_KEYSELECT_SEAL:return BASE_SEAL_KEY;case SGX_KEYSELECT_REPORT:return BASE_REPORT_KEY;case SGX_KEYSELECT_EINITTOKEN:return BASE_EINITTOKEN_KEY;case SGX_KEYSELECT_PROVISION:return BASE_PROVISION_KEY;case SGX_KEYSELECT_PROVISION_SEAL:return BASE_PROV_SEAL_KEY;}// Should not come here - error should have been reported// when the key name is not supported in the caller.return (uint8_t*)0;
}
mac存储在report结构中。
typedef struct _report_t /* 432 bytes */
{sgx_report_body_t body;sgx_key_id_t key_id; /* (384) KeyID used for diversifying the key tree */sgx_mac_t mac; /* (416) The Message Authentication Code over this structure. */
} sgx_report_t;
双方DH公钥的hash值存储在boby结构体的 sgx_report_data_t report_data字段;
对端拿到report之后,即可利用相同的参数生成一样的mac key。其中SGX保证了BASE_REPORT_KEY的一致性,即同一平台上获取的BASE_REPORT_KEY是一样的。
三、本地认证详细流程
注:以enclave1 表示认证发起端,enclave2 表示验证端。
本地认证有两种形式,其一,两个enclave同属于一个app,消息流程通过api调用即可完成;另一种,两个enclave分别属于各自的app,但在同一平台上,消息可通过socket等方式同步。以下说明不做区分。
以下流程说明标号和图示有所区别,会对消息信息加以详细说明;
1、双方分别调用sgx_create_enclave创建各自的enclave。
2、双方分别调用sgx_dh_init_session初始化各自的dh session。发起端设置自己角色为SGX_DH_SESSION_INITIATOR,状态为SGX_DH_SESSION_INITIATOR_WAIT_M1;验证端设置角色为SGX_DH_SESSION_RESPONDER,状态为SGX_DH_SESSION_STATE_RESET。
3.enclave1向enclave2请求msg1和session ID。
4.msg1包含enclave2的target info, ecdh算法的公钥。enclave2调用dh_generate_message1生成msg1,返回给enclave1,msg1明文传输;
target info包含信息如下:
$4 = {mr_enclave = {m = {0x19, 0x35, 0x1a, 0xed, 0xef, 0xc8, 0xe9, 0x87, 0xa6, 0xda, 0x91, 0xe6, 0x10, 0x8, 0xb3, 0x77, 0xc4, 0xa8, 0xbb, 0x1, 0xef, 0x53, 0x26, 0x70, 0xd1, 0xc6, 0xd2, 0x4e, 0x8d, 0x4c, 0x5f, 0x28}}, attributes = {flags = 0x7, xfrm = 0x7}, reserved1 = {0x0, 0x0}, config_svn = 0x0, misc_select = 0x0, reserved2 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, config_id = {0x0 <repeats 64 times>}, reserved3 = {0x0 <repeats 384 times>}
}
5.enclave1调用sgx_dh_initiator_proc_msg1处理msg1,生成msg2,真实处理函数为dh_generate_message2,gdb调用栈如下:
#0 dh_generate_message2 (msg1=0x7ffff63f9430, g_b=0x7ffff63f8dc0, dh_smk=0x7ffff63f8e00, msg2=0x7ffff63f9230) at ec_dh.cpp:239
#1 0x00007ffff6033986 in dh_initiator_proc_msg1<dh_generate_message2> (msg1=0x7ffff63f9430, msg2=0x7ffff63f9230, sgx_dh_session=0x7ffff63f8e80)at ec_dh.cpp:653
#2 0x00007ffff60336fe in sgx_LAv1_initiator_proc_msg1 (msg1=0x7ffff63f9430, msg2=0x7ffff63f9230, sgx_dh_session=0x7ffff63f8e80) at ec_dh.cpp:699
处理流程:
1)enclave1生成自己的ecdh密钥对,并用enclave2的传送的公钥计算一个sgx_ecc256_compute_shared_dhkey shared key;然后调用derive_key生成msg2的对称密钥dh_smk;
2)enclave1计算自己的公钥和enclave2公钥的hash值;存入report_data
3)report_data第32字节存储kdf算法的id;
4)调用sgx_create_report获取report,输入参数:enclave2的target info,report_data;
会调到do_ereport函数,为汇编实现,汇编的核心为ENCLU指令。
此处处理逻辑看第二章列出的SIM代码;
5)将report拷贝到msg2,并计算report的MAC值,密钥为dh_smk,存储在msg2的mac字段中;
6.发送msg2到enclave2,
7.enclave2调用sgx_dh_responder_proc_msg2处理msg2,生成msg3;
1)首先用enclave1的公钥,计算shared key,导出对称密钥dh_smk;
2)验证msg2的mac值,验证msg2->report.body.report_data是否是双方公钥的sha256结果。
3)调用sgx_verify_report验证msg2->report,包括一些校验及report的MAX值,其中用do_egetkey生成MAC算法的key,即调用EGETKEY指令并导出report key;SIM关键代码如下:
switch (kr->key_name) {case SGX_KEYSELECT_REPORT:// assemble derivation datadd.size = sizeof(dd_report_key_t);memcpy(&dd.ddrk.attributes, &cur_secs->attributes, sizeof(sgx_attributes_t));memcpy(dd.ddrk.csr_owner_epoch, SIMU_OWNER_EPOCH_MSR, sizeof(se_owner_epoch_t));memcpy(&dd.ddrk.cpu_svn,&(g_global_data_sim.cpusvn_sim),sizeof(sgx_cpu_svn_t));memcpy(&dd.ddrk.mrenclave, &cur_secs->mr_enclave, sizeof(sgx_measurement_t));memcpy(&dd.ddrk.key_id, &kr->key_id, sizeof(sgx_key_id_t));break;
其中kr->key_id为对端enclave1传过来的keyid,导出函数为derive_key(&dd, okey);同样会调用get_base_key。
4)msg2处理完成后,生成msg3,msg3和msg2包含信息基本一致。
5)计算对称密钥aek,用于后续消息的加密传输;
6)enclave2可以额外验证一些msg2的信息,通过sgx_dh_session_enclave_identity_t结构体收集:
typedef struct _sgx_dh_session_enclave_identity_t
{sgx_cpu_svn_t cpu_svn;sgx_misc_select_t misc_select;uint8_t reserved_1[28];sgx_attributes_t attributes;sgx_measurement_t mr_enclave;uint8_t reserved_2[32];sgx_measurement_t mr_signer;uint8_t reserved_3[96];sgx_prod_id_t isv_prod_id;sgx_isv_svn_t isv_svn;
} sgx_dh_session_enclave_identity_t;
8.调用sgx_dh_initiator_proc_msg3处理msg3,流程 和处理msg2一致,同样也会生成对称加密的aek用于后续数据加密传输。enclave1也可以做一些额外校验。
9.至此整个本地认证流程结束。就可以调用sgx_rijndael128GCM_encrypt和sgx_rijndael128GCM_decrypt用对称算法传输加密消息了。
代码角度理解SGX的认证机制(一):本地认证相关推荐
- 代码角度理解SGX的认证机制(三):远程认证
SGX 远程证明 和EPID证明协议不同,SGX不允许信任各方充当EPID验证的角色.而是由intel提供一个全球在线验证机构叫做intel 认证服务 (IAS). EPID认证协议涉及两个intel ...
- Node.js数据库与身份验证(MySQL,前后端身份认证:Session 认证机制,JWT认证机制)
目录 MySQL SQL 语句语法 where 条件.and 和 or 运算符.order by 排序.count(*) 函数 在express项目中操作 MySQL 安装与配置 mysql 模块 1 ...
- 常用的认证机制之session认证和token认证
一.session认证 1.session认证的过程: 前端输入用户名和密码进行登录操作,后端拿到用户名和密码后,会把md5进行加密,加密之后,拿上加密后的密文到用户表中查找密文是否一致,判断用户是否 ...
- 身份认证——session认证机制与JWT认证机制(入门到使用)
首先我们要了解什么是身份认证(Authentication)? 身份认证也叫身份验证或者鉴权,指通过一定的手段来完成对用户身份的验证 我们会使用session和JWT认证机制进行开发,那么我们在什么情 ...
- 配置用户通过Telnet登录设备的身份认证(AAA本地认证)
背景信息 用户通过Telnet登录设备时,设备上必须配置验证方式,否则用户无法成功登录设备.设备支持不认证.密码认证和AAA认证三种用户界面的验证方式,其中AAA认证方式安全性最高. 采用AAA本地认 ...
- 从代码角度理解什么是蜜罐
一.蜜罐概念 1.1 蜜罐的定义 百度百科:蜜罐技术本质上是一种对攻击方进行欺骗的技术,通过布置一些作为诱饵的主机.网络服务或者信息,诱使攻击方对它们实施攻击,从而可以对攻击行为进行捕获和分析,了解攻 ...
- node.js学习总结:node.js的内置模块,模块化,npm与包 express,前后端身份认证 JWT认证机制
node.js学习总结 什么是node.js node.js的内置模块 fs系统模块 path路径模块 http模块 模块化 npm与包 express express路由 express+mysql ...
- Windows认证机制详解(借物表在文章末尾)
一.本地认证 基础知识 Windows系统在本地认证过程中,操作系统会要求用户输入密码作为凭证去做身份验证. 在验证过程中,系统并不保存明文密码,而是将用户输入的密码转变为NTLM hash(也叫NT ...
- Mysql、通信认证机制<前端学习笔记>
Mysql MySQL.Oracle.SQL Server 属于传统型数据库 (又叫:关系型数据库或SQL数据库) Mongondb 属于 新型数据库(又叫:非关系型数据库或NoSQL数据库) SQL ...
最新文章
- 字符串匹配算法 KMP
- C#中的MessageBox消息对话框
- OpenCV几何变换的实例(附完整代码)
- php项目从本地apache移到linux的nginx上,遇到的一些访问权限和报错的问题。
- A.PHP读取txt文本文件并分页显示的方法
- iPhone系统更新提醒怎么关闭?
- logstash mysql 准实时同步到 elasticsearch
- 孔茨的现代管理理论的十一个流派
- 阿里巴巴Java开发手册(华山版)
- 如何将网易云ncm格式转换为mp3格式
- 谷歌搜索语句实例(持续更新)
- 谷歌chrome浏览器 抖动问题
- Unity基础到入门-导航系统(Navigation)
- 怎么样实现一台电脑上两个mysql自由切换版本
- 【jQwidgets】jqxComboBox
- 【Android】软件开发中遇到的LUT
- 【FinE】资产组合理论(2) 均值方差模型
- NFT Insider #59:a16z推出6亿美元基金专用于游戏初创公司,The Sandbox发布LAND持有者路线图
- 更专业的过等保服务,华为云等保合规解决方案值得选择!
- 前端网格布局grid