-
Notifications
You must be signed in to change notification settings - Fork 80
/
sgx-remote-attest.c
337 lines (292 loc) · 9.75 KB
/
sgx-remote-attest.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
/* Copyright (C) 1991-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <sgx-lib.h>
#include <sgx-shared.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <polarssl/rsa.h>
#include <polarssl/sha256.h>
int sgx_remote_attest_challenger(const char *target_ip, int target_port, const char *challenge)
{
//Network information of Target enclave
int target_fd;
report_t quote;
unsigned char *rsa_N, *rsa_E;
rsa_context rsa;
unsigned char hash[32], sign[32];
rsa_N = malloc(sizeof(mpi));
rsa_E = malloc(sizeof(mpi));
//Connect to Target enclave
puts("Connecting to Target enclave ...");
target_fd = sgx_connect_server(target_ip, target_port);
if(target_fd < 0) {
puts("sgx_connect_server error\n");
return -1;
}
puts("Target enclave connected!");
//Send challenge
puts("Sending challenge to Target enclave ...");
challenge = "Are you enclave?";
if(sgx_write_sock(target_fd, (void *)challenge, strlen(challenge)) < 0) {
puts("sgx_write_sock error\n");
goto failed;
}
puts("Waiting for RSA key and QUOTE ...");
//Receive rsa_N
memset(rsa_N, 0, sizeof(mpi));
if(sgx_read_sock(target_fd, rsa_N, sizeof(mpi)) <= 0) {
puts("sgx_read_sock error\n");
goto failed;
}
puts("Received rsa_N from Target enclave");
//Receive rsa_E
memset(rsa_E, 0, sizeof(mpi));
if(sgx_read_sock(target_fd, rsa_E, sizeof(mpi)) <= 0) {
puts("sgx_read_sock error\n");
goto failed;
}
puts("Received rsa_E from Target enclave");
//Receive QUOTE
memset("e, 0, sizeof(quote));
if(sgx_get_report(target_fd, "e) < 0) {
puts("sgx_get_report error\n");
goto failed;
}
puts("Received QUOTE from Target enclave");
//Verify QUOTE
mpi_read_binary(&rsa.N, rsa_N, sizeof(mpi));
mpi_read_binary(&rsa.E, rsa_E, sizeof(mpi));
rsa.len = (mpi_msb(&rsa.N)+7)>>3;
sha256((unsigned char *)"e, sizeof(report_t), hash, 0);
memcpy(sign, "e.mac, 16);
if(rsa_pkcs1_verify(&rsa, NULL, NULL, RSA_PUBLIC,
POLARSSL_MD_NONE, 0, hash, sign) != 0) {
puts("Failed to verify!\n");
close(target_fd);
goto failed;
}
puts("Verify Success!");
return 1;
failed:
close(target_fd);
return -1;
}
int sgx_remote_attest_target(int challenger_port, int quote_port, char *conf)
{
// Quoting enclave in same platform
const char *quote_ip = "127.0.0.1";
targetinfo_t targetinfo;
unsigned char nonce[64];
char read_buf[512];
report_t report;
report_t report_send;
report_t quote;
int client_fd, quote_fd;
sigstruct_t *sigstruct;
char *resultmsg;
keyrequest_t keyreq;
unsigned char report_key[DEVICE_KEY_LENGTH];
unsigned char *rsa_N, *rsa_E;
rsa_N = malloc(sizeof(mpi));
rsa_E = malloc(sizeof(mpi));
//server socket for Challenger
puts("Listening to Challenger ...");
client_fd = sgx_make_server(challenger_port);
if(client_fd < 0) {
puts("sgx_make_server error\n");
return -1;
}
puts("Challenger accepted");
//Get challenge data from Challenger
puts("Receiving challenge data ...");
memset(read_buf, 0, 512);
if (sgx_read_sock(client_fd, read_buf, 512) <= 0) {
puts("sgx_read_sock error\n");
return -1;
}
printf("Challeger msg: %s\n", read_buf);
//Connect to Quoting enclave
puts("Connecting to Quoting enclave ...");
quote_fd = sgx_connect_server(quote_ip, quote_port);
if(quote_fd < 0) {
puts("sgx_connect_server error\n");
close(client_fd);
return -1;
}
puts("Quoting enclave connected!");
//Get SIGSTRUCT of Quoting enclave
sigstruct = sgx_load_sigstruct(conf);
puts("Got SIGSTRUCT!");
//EREPORT with sigstruct
puts("Sending REPORT to Quoting enclave ...");
memcpy(&targetinfo.measurement, &sigstruct->enclaveHash, 32);
memcpy(&targetinfo.attributes, &sigstruct->attributes, 16);
memcpy(&targetinfo.miscselect, &sigstruct->miscselect, 4);
sgx_report(&targetinfo, nonce, &report_send);
if(sgx_write_sock(quote_fd, &report_send, sizeof(report_t)) < 0) {
puts("sgx_write_sock error\n");
goto failed;
}
//Get REPORT from Quoting enclave
if(sgx_get_report(quote_fd, &report) < 0) {
puts("sgx_get_report error\n");
goto failed;
}
puts("Received REPORT from Quoting enclave");
//Get Report key from QEMU
keyreq.keyname = REPORT_KEY;
memcpy(&keyreq.keyid, &report.keyid, 16);
memcpy(&keyreq.miscmask, &report.miscselect, 4);
sgx_getkey(&keyreq, report_key);
puts("Received Report Key");
//Check MAC matching
if(sgx_match_mac(report_key, &report) < 0) {
puts("Mac not match!\n");
goto failed;
}
puts("MAC match, PASS!");
//Send intra attestaion result to Quoting enclave
puts("Sending result message to Quoting enclave ...");
resultmsg = "Good";
if(sgx_write_sock(quote_fd, resultmsg, strlen(resultmsg)) < 0) {
puts("sgx_write_sock error\n");
}
puts("Waiting for RSA key and QUOTE ...");
//Receive rsa_N
memset(rsa_N, 0, sizeof(mpi));
if(sgx_read_sock(quote_fd, rsa_N, sizeof(mpi)) <= 0) {
puts("sgx_read_sock error\n");
goto failed;
}
puts("Received rsa_N from Quoting enclave");
//Receive rsa_E
memset(rsa_E, 0, sizeof(mpi));
if(sgx_read_sock(quote_fd, rsa_E, sizeof(mpi)) <= 0) {
puts("sgx_read_sock error\n");
goto failed;
}
puts("Received rsa_E from Quoting enclave");
//Receive QUOTE
memset("e, 0, sizeof(quote));
if(sgx_get_report(quote_fd, "e) < 0) {
goto failed;
}
puts("Received QUOTE from Quoting enclave");
//send to challenger
puts("Sending RSA & QUOTE to Challenger");
if(sgx_write_sock(client_fd, rsa_N, sizeof(mpi)) < 0) {
puts("sgx_write_sock error\n");
goto failed;
}
if(sgx_write_sock(client_fd, rsa_E, sizeof(mpi)) < 0) {
puts("sgx_write_sock error\n");
goto failed;
}
if(sgx_write_sock(client_fd, "e, sizeof(report_t)) < 0) {
puts("sgx_write_sock error\n");
goto failed;
}
close(quote_fd);
close(client_fd);
puts("Target enclave end");
return 1;
failed:
close(quote_fd);
close(client_fd);
return -1;
}
int sgx_remote_attest_quote(int target_port)
{
report_t report;
report_t report_send;
targetinfo_t targetinfo;
unsigned char nonce[64];
char read_buf[512];
int client_fd;
keyrequest_t keyreq;
unsigned char report_key[DEVICE_KEY_LENGTH];
const char *pers = "rsa_genkey";
unsigned char *rsa_N, *rsa_E;
rsa_N = malloc(sizeof(mpi));
rsa_E = malloc(sizeof(mpi));
puts("Listening to Target enclave ...");
client_fd = sgx_make_server(target_port);
if(client_fd < 0) {
puts("sgx_make_server error\n");
return -1;
}
puts("Target enclave accepted");
//Get REPORT from Target enclave
if(sgx_get_report(client_fd, &report) < 0) {
puts("sgx_get_report error\n");
goto failed;
}
puts("Received REPORT from Target enclave");
//Get Report key from QEMU
keyreq.keyname = REPORT_KEY;
memcpy(&keyreq.keyid, &report.keyid, 16);
memcpy(&keyreq.miscmask, &report.miscselect, 4);
sgx_getkey(&keyreq, report_key);
puts("Received Report Key");
//Check MAC matching
if(sgx_match_mac(report_key, &report) < 0) {
puts("Mac not match!\n");
goto failed;
}
puts("MAC match, PASS!");
//EREPORT with given report
puts("Sending REPORT to Target enclave ...");
memcpy(&targetinfo.measurement, &report.mrenclave, 32);
memcpy(&targetinfo.attributes, &report.attributes, 16);
memcpy(&targetinfo.miscselect, &report.miscselect, 4);
sgx_report(&targetinfo, nonce, &report_send);
if(sgx_write_sock(client_fd, &report_send, sizeof(report_t)) < 0) {
puts("sgx_write_sock error\n");
goto failed;
}
//Get intra attestation result of Target enclave
memset(read_buf, 0, sizeof(read_buf));
if(sgx_read_sock(client_fd, read_buf, sizeof(read_buf)) <= 0) {
puts("sgx_read_sock error\n");
goto failed;
}
printf("Target enclave msg: %s\n", read_buf);
if(strcmp(read_buf, "Good") != 0) {
puts("Target enclave denied");
goto failed;
}
//Make RSA & QUOTE
sgx_make_quote(pers, &report, rsa_N, rsa_E);
//Send quote
if(sgx_write_sock(client_fd, rsa_N, sizeof(mpi)) < 0) {
puts("sgx_write_sock error\n");
goto failed;
}
if(sgx_write_sock(client_fd, rsa_E, sizeof(mpi)) < 0) {
puts("sgx_write_sock error\n");
goto failed;
}
if(sgx_write_sock(client_fd, &report, sizeof(report_t)) < 0) {
puts("sgx_write_sock error\n");
goto failed;
}
close(client_fd);
puts("Quoting enclave end");
return 1;
failed:
close(client_fd);
return -1;
}