xref: /aosp_15_r20/external/linux-kselftest/tools/testing/selftests/sgx/sigstruct.c (revision 053f45be4e351dfd5e965df293cd45b779f579ee)
1*053f45beSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0
2*053f45beSAndroid Build Coastguard Worker /*  Copyright(c) 2016-20 Intel Corporation. */
3*053f45beSAndroid Build Coastguard Worker 
4*053f45beSAndroid Build Coastguard Worker #define _GNU_SOURCE
5*053f45beSAndroid Build Coastguard Worker #include <assert.h>
6*053f45beSAndroid Build Coastguard Worker #include <getopt.h>
7*053f45beSAndroid Build Coastguard Worker #include <stdbool.h>
8*053f45beSAndroid Build Coastguard Worker #include <stdint.h>
9*053f45beSAndroid Build Coastguard Worker #include <stdio.h>
10*053f45beSAndroid Build Coastguard Worker #include <stdlib.h>
11*053f45beSAndroid Build Coastguard Worker #include <string.h>
12*053f45beSAndroid Build Coastguard Worker #include <sys/stat.h>
13*053f45beSAndroid Build Coastguard Worker #include <sys/types.h>
14*053f45beSAndroid Build Coastguard Worker #include <unistd.h>
15*053f45beSAndroid Build Coastguard Worker #include <openssl/err.h>
16*053f45beSAndroid Build Coastguard Worker #include <openssl/pem.h>
17*053f45beSAndroid Build Coastguard Worker #include "defines.h"
18*053f45beSAndroid Build Coastguard Worker #include "main.h"
19*053f45beSAndroid Build Coastguard Worker 
20*053f45beSAndroid Build Coastguard Worker /*
21*053f45beSAndroid Build Coastguard Worker  * FIXME: OpenSSL 3.0 has deprecated some functions. For now just ignore
22*053f45beSAndroid Build Coastguard Worker  * the warnings.
23*053f45beSAndroid Build Coastguard Worker  */
24*053f45beSAndroid Build Coastguard Worker #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
25*053f45beSAndroid Build Coastguard Worker 
26*053f45beSAndroid Build Coastguard Worker struct q1q2_ctx {
27*053f45beSAndroid Build Coastguard Worker 	BN_CTX *bn_ctx;
28*053f45beSAndroid Build Coastguard Worker 	BIGNUM *m;
29*053f45beSAndroid Build Coastguard Worker 	BIGNUM *s;
30*053f45beSAndroid Build Coastguard Worker 	BIGNUM *q1;
31*053f45beSAndroid Build Coastguard Worker 	BIGNUM *qr;
32*053f45beSAndroid Build Coastguard Worker 	BIGNUM *q2;
33*053f45beSAndroid Build Coastguard Worker };
34*053f45beSAndroid Build Coastguard Worker 
free_q1q2_ctx(struct q1q2_ctx * ctx)35*053f45beSAndroid Build Coastguard Worker static void free_q1q2_ctx(struct q1q2_ctx *ctx)
36*053f45beSAndroid Build Coastguard Worker {
37*053f45beSAndroid Build Coastguard Worker 	BN_CTX_free(ctx->bn_ctx);
38*053f45beSAndroid Build Coastguard Worker 	BN_free(ctx->m);
39*053f45beSAndroid Build Coastguard Worker 	BN_free(ctx->s);
40*053f45beSAndroid Build Coastguard Worker 	BN_free(ctx->q1);
41*053f45beSAndroid Build Coastguard Worker 	BN_free(ctx->qr);
42*053f45beSAndroid Build Coastguard Worker 	BN_free(ctx->q2);
43*053f45beSAndroid Build Coastguard Worker }
44*053f45beSAndroid Build Coastguard Worker 
alloc_q1q2_ctx(const uint8_t * s,const uint8_t * m,struct q1q2_ctx * ctx)45*053f45beSAndroid Build Coastguard Worker static bool alloc_q1q2_ctx(const uint8_t *s, const uint8_t *m,
46*053f45beSAndroid Build Coastguard Worker 			   struct q1q2_ctx *ctx)
47*053f45beSAndroid Build Coastguard Worker {
48*053f45beSAndroid Build Coastguard Worker 	ctx->bn_ctx = BN_CTX_new();
49*053f45beSAndroid Build Coastguard Worker 	ctx->s = BN_bin2bn(s, SGX_MODULUS_SIZE, NULL);
50*053f45beSAndroid Build Coastguard Worker 	ctx->m = BN_bin2bn(m, SGX_MODULUS_SIZE, NULL);
51*053f45beSAndroid Build Coastguard Worker 	ctx->q1 = BN_new();
52*053f45beSAndroid Build Coastguard Worker 	ctx->qr = BN_new();
53*053f45beSAndroid Build Coastguard Worker 	ctx->q2 = BN_new();
54*053f45beSAndroid Build Coastguard Worker 
55*053f45beSAndroid Build Coastguard Worker 	if (!ctx->bn_ctx || !ctx->s || !ctx->m || !ctx->q1 || !ctx->qr ||
56*053f45beSAndroid Build Coastguard Worker 	    !ctx->q2) {
57*053f45beSAndroid Build Coastguard Worker 		free_q1q2_ctx(ctx);
58*053f45beSAndroid Build Coastguard Worker 		return false;
59*053f45beSAndroid Build Coastguard Worker 	}
60*053f45beSAndroid Build Coastguard Worker 
61*053f45beSAndroid Build Coastguard Worker 	return true;
62*053f45beSAndroid Build Coastguard Worker }
63*053f45beSAndroid Build Coastguard Worker 
reverse_bytes(void * data,int length)64*053f45beSAndroid Build Coastguard Worker static void reverse_bytes(void *data, int length)
65*053f45beSAndroid Build Coastguard Worker {
66*053f45beSAndroid Build Coastguard Worker 	int i = 0;
67*053f45beSAndroid Build Coastguard Worker 	int j = length - 1;
68*053f45beSAndroid Build Coastguard Worker 	uint8_t temp;
69*053f45beSAndroid Build Coastguard Worker 	uint8_t *ptr = data;
70*053f45beSAndroid Build Coastguard Worker 
71*053f45beSAndroid Build Coastguard Worker 	while (i < j) {
72*053f45beSAndroid Build Coastguard Worker 		temp = ptr[i];
73*053f45beSAndroid Build Coastguard Worker 		ptr[i] = ptr[j];
74*053f45beSAndroid Build Coastguard Worker 		ptr[j] = temp;
75*053f45beSAndroid Build Coastguard Worker 		i++;
76*053f45beSAndroid Build Coastguard Worker 		j--;
77*053f45beSAndroid Build Coastguard Worker 	}
78*053f45beSAndroid Build Coastguard Worker }
79*053f45beSAndroid Build Coastguard Worker 
calc_q1q2(const uint8_t * s,const uint8_t * m,uint8_t * q1,uint8_t * q2)80*053f45beSAndroid Build Coastguard Worker static bool calc_q1q2(const uint8_t *s, const uint8_t *m, uint8_t *q1,
81*053f45beSAndroid Build Coastguard Worker 		      uint8_t *q2)
82*053f45beSAndroid Build Coastguard Worker {
83*053f45beSAndroid Build Coastguard Worker 	struct q1q2_ctx ctx;
84*053f45beSAndroid Build Coastguard Worker 	int len;
85*053f45beSAndroid Build Coastguard Worker 
86*053f45beSAndroid Build Coastguard Worker 	if (!alloc_q1q2_ctx(s, m, &ctx)) {
87*053f45beSAndroid Build Coastguard Worker 		fprintf(stderr, "Not enough memory for Q1Q2 calculation\n");
88*053f45beSAndroid Build Coastguard Worker 		return false;
89*053f45beSAndroid Build Coastguard Worker 	}
90*053f45beSAndroid Build Coastguard Worker 
91*053f45beSAndroid Build Coastguard Worker 	if (!BN_mul(ctx.q1, ctx.s, ctx.s, ctx.bn_ctx))
92*053f45beSAndroid Build Coastguard Worker 		goto out;
93*053f45beSAndroid Build Coastguard Worker 
94*053f45beSAndroid Build Coastguard Worker 	if (!BN_div(ctx.q1, ctx.qr, ctx.q1, ctx.m, ctx.bn_ctx))
95*053f45beSAndroid Build Coastguard Worker 		goto out;
96*053f45beSAndroid Build Coastguard Worker 
97*053f45beSAndroid Build Coastguard Worker 	if (BN_num_bytes(ctx.q1) > SGX_MODULUS_SIZE) {
98*053f45beSAndroid Build Coastguard Worker 		fprintf(stderr, "Too large Q1 %d bytes\n",
99*053f45beSAndroid Build Coastguard Worker 			BN_num_bytes(ctx.q1));
100*053f45beSAndroid Build Coastguard Worker 		goto out;
101*053f45beSAndroid Build Coastguard Worker 	}
102*053f45beSAndroid Build Coastguard Worker 
103*053f45beSAndroid Build Coastguard Worker 	if (!BN_mul(ctx.q2, ctx.s, ctx.qr, ctx.bn_ctx))
104*053f45beSAndroid Build Coastguard Worker 		goto out;
105*053f45beSAndroid Build Coastguard Worker 
106*053f45beSAndroid Build Coastguard Worker 	if (!BN_div(ctx.q2, NULL, ctx.q2, ctx.m, ctx.bn_ctx))
107*053f45beSAndroid Build Coastguard Worker 		goto out;
108*053f45beSAndroid Build Coastguard Worker 
109*053f45beSAndroid Build Coastguard Worker 	if (BN_num_bytes(ctx.q2) > SGX_MODULUS_SIZE) {
110*053f45beSAndroid Build Coastguard Worker 		fprintf(stderr, "Too large Q2 %d bytes\n",
111*053f45beSAndroid Build Coastguard Worker 			BN_num_bytes(ctx.q2));
112*053f45beSAndroid Build Coastguard Worker 		goto out;
113*053f45beSAndroid Build Coastguard Worker 	}
114*053f45beSAndroid Build Coastguard Worker 
115*053f45beSAndroid Build Coastguard Worker 	len = BN_bn2bin(ctx.q1, q1);
116*053f45beSAndroid Build Coastguard Worker 	reverse_bytes(q1, len);
117*053f45beSAndroid Build Coastguard Worker 	len = BN_bn2bin(ctx.q2, q2);
118*053f45beSAndroid Build Coastguard Worker 	reverse_bytes(q2, len);
119*053f45beSAndroid Build Coastguard Worker 
120*053f45beSAndroid Build Coastguard Worker 	free_q1q2_ctx(&ctx);
121*053f45beSAndroid Build Coastguard Worker 	return true;
122*053f45beSAndroid Build Coastguard Worker out:
123*053f45beSAndroid Build Coastguard Worker 	free_q1q2_ctx(&ctx);
124*053f45beSAndroid Build Coastguard Worker 	return false;
125*053f45beSAndroid Build Coastguard Worker }
126*053f45beSAndroid Build Coastguard Worker 
127*053f45beSAndroid Build Coastguard Worker struct sgx_sigstruct_payload {
128*053f45beSAndroid Build Coastguard Worker 	struct sgx_sigstruct_header header;
129*053f45beSAndroid Build Coastguard Worker 	struct sgx_sigstruct_body body;
130*053f45beSAndroid Build Coastguard Worker };
131*053f45beSAndroid Build Coastguard Worker 
check_crypto_errors(void)132*053f45beSAndroid Build Coastguard Worker static bool check_crypto_errors(void)
133*053f45beSAndroid Build Coastguard Worker {
134*053f45beSAndroid Build Coastguard Worker 	int err;
135*053f45beSAndroid Build Coastguard Worker 	bool had_errors = false;
136*053f45beSAndroid Build Coastguard Worker 	const char *filename;
137*053f45beSAndroid Build Coastguard Worker 	int line;
138*053f45beSAndroid Build Coastguard Worker 	char str[256];
139*053f45beSAndroid Build Coastguard Worker 
140*053f45beSAndroid Build Coastguard Worker 	for ( ; ; ) {
141*053f45beSAndroid Build Coastguard Worker 		if (ERR_peek_error() == 0)
142*053f45beSAndroid Build Coastguard Worker 			break;
143*053f45beSAndroid Build Coastguard Worker 
144*053f45beSAndroid Build Coastguard Worker 		had_errors = true;
145*053f45beSAndroid Build Coastguard Worker 		err = ERR_get_error_line(&filename, &line);
146*053f45beSAndroid Build Coastguard Worker 		ERR_error_string_n(err, str, sizeof(str));
147*053f45beSAndroid Build Coastguard Worker 		fprintf(stderr, "crypto: %s: %s:%d\n", str, filename, line);
148*053f45beSAndroid Build Coastguard Worker 	}
149*053f45beSAndroid Build Coastguard Worker 
150*053f45beSAndroid Build Coastguard Worker 	return had_errors;
151*053f45beSAndroid Build Coastguard Worker }
152*053f45beSAndroid Build Coastguard Worker 
get_modulus(RSA * key)153*053f45beSAndroid Build Coastguard Worker static inline const BIGNUM *get_modulus(RSA *key)
154*053f45beSAndroid Build Coastguard Worker {
155*053f45beSAndroid Build Coastguard Worker 	const BIGNUM *n;
156*053f45beSAndroid Build Coastguard Worker 
157*053f45beSAndroid Build Coastguard Worker 	RSA_get0_key(key, &n, NULL, NULL);
158*053f45beSAndroid Build Coastguard Worker 	return n;
159*053f45beSAndroid Build Coastguard Worker }
160*053f45beSAndroid Build Coastguard Worker 
gen_sign_key(void)161*053f45beSAndroid Build Coastguard Worker static RSA *gen_sign_key(void)
162*053f45beSAndroid Build Coastguard Worker {
163*053f45beSAndroid Build Coastguard Worker 	unsigned long sign_key_length;
164*053f45beSAndroid Build Coastguard Worker 	BIO *bio;
165*053f45beSAndroid Build Coastguard Worker 	RSA *key;
166*053f45beSAndroid Build Coastguard Worker 
167*053f45beSAndroid Build Coastguard Worker 	sign_key_length = (unsigned long)&sign_key_end -
168*053f45beSAndroid Build Coastguard Worker 			  (unsigned long)&sign_key;
169*053f45beSAndroid Build Coastguard Worker 
170*053f45beSAndroid Build Coastguard Worker 	bio = BIO_new_mem_buf(&sign_key, sign_key_length);
171*053f45beSAndroid Build Coastguard Worker 	if (!bio)
172*053f45beSAndroid Build Coastguard Worker 		return NULL;
173*053f45beSAndroid Build Coastguard Worker 
174*053f45beSAndroid Build Coastguard Worker 	key = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL);
175*053f45beSAndroid Build Coastguard Worker 	BIO_free(bio);
176*053f45beSAndroid Build Coastguard Worker 
177*053f45beSAndroid Build Coastguard Worker 	return key;
178*053f45beSAndroid Build Coastguard Worker }
179*053f45beSAndroid Build Coastguard Worker 
180*053f45beSAndroid Build Coastguard Worker enum mrtags {
181*053f45beSAndroid Build Coastguard Worker 	MRECREATE = 0x0045544145524345,
182*053f45beSAndroid Build Coastguard Worker 	MREADD = 0x0000000044444145,
183*053f45beSAndroid Build Coastguard Worker 	MREEXTEND = 0x00444E4554584545,
184*053f45beSAndroid Build Coastguard Worker };
185*053f45beSAndroid Build Coastguard Worker 
mrenclave_update(EVP_MD_CTX * ctx,const void * data)186*053f45beSAndroid Build Coastguard Worker static bool mrenclave_update(EVP_MD_CTX *ctx, const void *data)
187*053f45beSAndroid Build Coastguard Worker {
188*053f45beSAndroid Build Coastguard Worker 	if (!EVP_DigestUpdate(ctx, data, 64)) {
189*053f45beSAndroid Build Coastguard Worker 		fprintf(stderr, "digest update failed\n");
190*053f45beSAndroid Build Coastguard Worker 		return false;
191*053f45beSAndroid Build Coastguard Worker 	}
192*053f45beSAndroid Build Coastguard Worker 
193*053f45beSAndroid Build Coastguard Worker 	return true;
194*053f45beSAndroid Build Coastguard Worker }
195*053f45beSAndroid Build Coastguard Worker 
mrenclave_commit(EVP_MD_CTX * ctx,uint8_t * mrenclave)196*053f45beSAndroid Build Coastguard Worker static bool mrenclave_commit(EVP_MD_CTX *ctx, uint8_t *mrenclave)
197*053f45beSAndroid Build Coastguard Worker {
198*053f45beSAndroid Build Coastguard Worker 	unsigned int size;
199*053f45beSAndroid Build Coastguard Worker 
200*053f45beSAndroid Build Coastguard Worker 	if (!EVP_DigestFinal_ex(ctx, (unsigned char *)mrenclave, &size)) {
201*053f45beSAndroid Build Coastguard Worker 		fprintf(stderr, "digest commit failed\n");
202*053f45beSAndroid Build Coastguard Worker 		return false;
203*053f45beSAndroid Build Coastguard Worker 	}
204*053f45beSAndroid Build Coastguard Worker 
205*053f45beSAndroid Build Coastguard Worker 	if (size != 32) {
206*053f45beSAndroid Build Coastguard Worker 		fprintf(stderr, "invalid digest size = %u\n", size);
207*053f45beSAndroid Build Coastguard Worker 		return false;
208*053f45beSAndroid Build Coastguard Worker 	}
209*053f45beSAndroid Build Coastguard Worker 
210*053f45beSAndroid Build Coastguard Worker 	return true;
211*053f45beSAndroid Build Coastguard Worker }
212*053f45beSAndroid Build Coastguard Worker 
213*053f45beSAndroid Build Coastguard Worker struct mrecreate {
214*053f45beSAndroid Build Coastguard Worker 	uint64_t tag;
215*053f45beSAndroid Build Coastguard Worker 	uint32_t ssaframesize;
216*053f45beSAndroid Build Coastguard Worker 	uint64_t size;
217*053f45beSAndroid Build Coastguard Worker 	uint8_t reserved[44];
218*053f45beSAndroid Build Coastguard Worker } __attribute__((__packed__));
219*053f45beSAndroid Build Coastguard Worker 
220*053f45beSAndroid Build Coastguard Worker 
mrenclave_ecreate(EVP_MD_CTX * ctx,uint64_t blob_size)221*053f45beSAndroid Build Coastguard Worker static bool mrenclave_ecreate(EVP_MD_CTX *ctx, uint64_t blob_size)
222*053f45beSAndroid Build Coastguard Worker {
223*053f45beSAndroid Build Coastguard Worker 	struct mrecreate mrecreate;
224*053f45beSAndroid Build Coastguard Worker 	uint64_t encl_size;
225*053f45beSAndroid Build Coastguard Worker 
226*053f45beSAndroid Build Coastguard Worker 	for (encl_size = 0x1000; encl_size < blob_size; )
227*053f45beSAndroid Build Coastguard Worker 		encl_size <<= 1;
228*053f45beSAndroid Build Coastguard Worker 
229*053f45beSAndroid Build Coastguard Worker 	memset(&mrecreate, 0, sizeof(mrecreate));
230*053f45beSAndroid Build Coastguard Worker 	mrecreate.tag = MRECREATE;
231*053f45beSAndroid Build Coastguard Worker 	mrecreate.ssaframesize = 1;
232*053f45beSAndroid Build Coastguard Worker 	mrecreate.size = encl_size;
233*053f45beSAndroid Build Coastguard Worker 
234*053f45beSAndroid Build Coastguard Worker 	if (!EVP_DigestInit_ex(ctx, EVP_sha256(), NULL))
235*053f45beSAndroid Build Coastguard Worker 		return false;
236*053f45beSAndroid Build Coastguard Worker 
237*053f45beSAndroid Build Coastguard Worker 	return mrenclave_update(ctx, &mrecreate);
238*053f45beSAndroid Build Coastguard Worker }
239*053f45beSAndroid Build Coastguard Worker 
240*053f45beSAndroid Build Coastguard Worker struct mreadd {
241*053f45beSAndroid Build Coastguard Worker 	uint64_t tag;
242*053f45beSAndroid Build Coastguard Worker 	uint64_t offset;
243*053f45beSAndroid Build Coastguard Worker 	uint64_t flags; /* SECINFO flags */
244*053f45beSAndroid Build Coastguard Worker 	uint8_t reserved[40];
245*053f45beSAndroid Build Coastguard Worker } __attribute__((__packed__));
246*053f45beSAndroid Build Coastguard Worker 
mrenclave_eadd(EVP_MD_CTX * ctx,uint64_t offset,uint64_t flags)247*053f45beSAndroid Build Coastguard Worker static bool mrenclave_eadd(EVP_MD_CTX *ctx, uint64_t offset, uint64_t flags)
248*053f45beSAndroid Build Coastguard Worker {
249*053f45beSAndroid Build Coastguard Worker 	struct mreadd mreadd;
250*053f45beSAndroid Build Coastguard Worker 
251*053f45beSAndroid Build Coastguard Worker 	memset(&mreadd, 0, sizeof(mreadd));
252*053f45beSAndroid Build Coastguard Worker 	mreadd.tag = MREADD;
253*053f45beSAndroid Build Coastguard Worker 	mreadd.offset = offset;
254*053f45beSAndroid Build Coastguard Worker 	mreadd.flags = flags;
255*053f45beSAndroid Build Coastguard Worker 
256*053f45beSAndroid Build Coastguard Worker 	return mrenclave_update(ctx, &mreadd);
257*053f45beSAndroid Build Coastguard Worker }
258*053f45beSAndroid Build Coastguard Worker 
259*053f45beSAndroid Build Coastguard Worker struct mreextend {
260*053f45beSAndroid Build Coastguard Worker 	uint64_t tag;
261*053f45beSAndroid Build Coastguard Worker 	uint64_t offset;
262*053f45beSAndroid Build Coastguard Worker 	uint8_t reserved[48];
263*053f45beSAndroid Build Coastguard Worker } __attribute__((__packed__));
264*053f45beSAndroid Build Coastguard Worker 
mrenclave_eextend(EVP_MD_CTX * ctx,uint64_t offset,const uint8_t * data)265*053f45beSAndroid Build Coastguard Worker static bool mrenclave_eextend(EVP_MD_CTX *ctx, uint64_t offset,
266*053f45beSAndroid Build Coastguard Worker 			      const uint8_t *data)
267*053f45beSAndroid Build Coastguard Worker {
268*053f45beSAndroid Build Coastguard Worker 	struct mreextend mreextend;
269*053f45beSAndroid Build Coastguard Worker 	int i;
270*053f45beSAndroid Build Coastguard Worker 
271*053f45beSAndroid Build Coastguard Worker 	for (i = 0; i < 0x1000; i += 0x100) {
272*053f45beSAndroid Build Coastguard Worker 		memset(&mreextend, 0, sizeof(mreextend));
273*053f45beSAndroid Build Coastguard Worker 		mreextend.tag = MREEXTEND;
274*053f45beSAndroid Build Coastguard Worker 		mreextend.offset = offset + i;
275*053f45beSAndroid Build Coastguard Worker 
276*053f45beSAndroid Build Coastguard Worker 		if (!mrenclave_update(ctx, &mreextend))
277*053f45beSAndroid Build Coastguard Worker 			return false;
278*053f45beSAndroid Build Coastguard Worker 
279*053f45beSAndroid Build Coastguard Worker 		if (!mrenclave_update(ctx, &data[i + 0x00]))
280*053f45beSAndroid Build Coastguard Worker 			return false;
281*053f45beSAndroid Build Coastguard Worker 
282*053f45beSAndroid Build Coastguard Worker 		if (!mrenclave_update(ctx, &data[i + 0x40]))
283*053f45beSAndroid Build Coastguard Worker 			return false;
284*053f45beSAndroid Build Coastguard Worker 
285*053f45beSAndroid Build Coastguard Worker 		if (!mrenclave_update(ctx, &data[i + 0x80]))
286*053f45beSAndroid Build Coastguard Worker 			return false;
287*053f45beSAndroid Build Coastguard Worker 
288*053f45beSAndroid Build Coastguard Worker 		if (!mrenclave_update(ctx, &data[i + 0xC0]))
289*053f45beSAndroid Build Coastguard Worker 			return false;
290*053f45beSAndroid Build Coastguard Worker 	}
291*053f45beSAndroid Build Coastguard Worker 
292*053f45beSAndroid Build Coastguard Worker 	return true;
293*053f45beSAndroid Build Coastguard Worker }
294*053f45beSAndroid Build Coastguard Worker 
mrenclave_segment(EVP_MD_CTX * ctx,struct encl * encl,struct encl_segment * seg)295*053f45beSAndroid Build Coastguard Worker static bool mrenclave_segment(EVP_MD_CTX *ctx, struct encl *encl,
296*053f45beSAndroid Build Coastguard Worker 			      struct encl_segment *seg)
297*053f45beSAndroid Build Coastguard Worker {
298*053f45beSAndroid Build Coastguard Worker 	uint64_t end = seg->size;
299*053f45beSAndroid Build Coastguard Worker 	uint64_t offset;
300*053f45beSAndroid Build Coastguard Worker 
301*053f45beSAndroid Build Coastguard Worker 	for (offset = 0; offset < end; offset += PAGE_SIZE) {
302*053f45beSAndroid Build Coastguard Worker 		if (!mrenclave_eadd(ctx, seg->offset + offset, seg->flags))
303*053f45beSAndroid Build Coastguard Worker 			return false;
304*053f45beSAndroid Build Coastguard Worker 
305*053f45beSAndroid Build Coastguard Worker 		if (seg->measure) {
306*053f45beSAndroid Build Coastguard Worker 			if (!mrenclave_eextend(ctx, seg->offset + offset, seg->src + offset))
307*053f45beSAndroid Build Coastguard Worker 				return false;
308*053f45beSAndroid Build Coastguard Worker 		}
309*053f45beSAndroid Build Coastguard Worker 	}
310*053f45beSAndroid Build Coastguard Worker 
311*053f45beSAndroid Build Coastguard Worker 	return true;
312*053f45beSAndroid Build Coastguard Worker }
313*053f45beSAndroid Build Coastguard Worker 
encl_measure(struct encl * encl)314*053f45beSAndroid Build Coastguard Worker bool encl_measure(struct encl *encl)
315*053f45beSAndroid Build Coastguard Worker {
316*053f45beSAndroid Build Coastguard Worker 	uint64_t header1[2] = {0x000000E100000006, 0x0000000000010000};
317*053f45beSAndroid Build Coastguard Worker 	uint64_t header2[2] = {0x0000006000000101, 0x0000000100000060};
318*053f45beSAndroid Build Coastguard Worker 	struct sgx_sigstruct *sigstruct = &encl->sigstruct;
319*053f45beSAndroid Build Coastguard Worker 	struct sgx_sigstruct_payload payload;
320*053f45beSAndroid Build Coastguard Worker 	uint8_t digest[SHA256_DIGEST_LENGTH];
321*053f45beSAndroid Build Coastguard Worker 	unsigned int siglen;
322*053f45beSAndroid Build Coastguard Worker 	RSA *key = NULL;
323*053f45beSAndroid Build Coastguard Worker 	EVP_MD_CTX *ctx;
324*053f45beSAndroid Build Coastguard Worker 	int i;
325*053f45beSAndroid Build Coastguard Worker 
326*053f45beSAndroid Build Coastguard Worker 	memset(sigstruct, 0, sizeof(*sigstruct));
327*053f45beSAndroid Build Coastguard Worker 
328*053f45beSAndroid Build Coastguard Worker 	sigstruct->header.header1[0] = header1[0];
329*053f45beSAndroid Build Coastguard Worker 	sigstruct->header.header1[1] = header1[1];
330*053f45beSAndroid Build Coastguard Worker 	sigstruct->header.header2[0] = header2[0];
331*053f45beSAndroid Build Coastguard Worker 	sigstruct->header.header2[1] = header2[1];
332*053f45beSAndroid Build Coastguard Worker 	sigstruct->exponent = 3;
333*053f45beSAndroid Build Coastguard Worker 	sigstruct->body.attributes = SGX_ATTR_MODE64BIT;
334*053f45beSAndroid Build Coastguard Worker 	sigstruct->body.xfrm = 3;
335*053f45beSAndroid Build Coastguard Worker 
336*053f45beSAndroid Build Coastguard Worker 	/* sanity check */
337*053f45beSAndroid Build Coastguard Worker 	if (check_crypto_errors())
338*053f45beSAndroid Build Coastguard Worker 		goto err;
339*053f45beSAndroid Build Coastguard Worker 
340*053f45beSAndroid Build Coastguard Worker 	key = gen_sign_key();
341*053f45beSAndroid Build Coastguard Worker 	if (!key) {
342*053f45beSAndroid Build Coastguard Worker 		ERR_print_errors_fp(stdout);
343*053f45beSAndroid Build Coastguard Worker 		goto err;
344*053f45beSAndroid Build Coastguard Worker 	}
345*053f45beSAndroid Build Coastguard Worker 
346*053f45beSAndroid Build Coastguard Worker 	BN_bn2bin(get_modulus(key), sigstruct->modulus);
347*053f45beSAndroid Build Coastguard Worker 
348*053f45beSAndroid Build Coastguard Worker 	ctx = EVP_MD_CTX_create();
349*053f45beSAndroid Build Coastguard Worker 	if (!ctx)
350*053f45beSAndroid Build Coastguard Worker 		goto err;
351*053f45beSAndroid Build Coastguard Worker 
352*053f45beSAndroid Build Coastguard Worker 	if (!mrenclave_ecreate(ctx, encl->src_size))
353*053f45beSAndroid Build Coastguard Worker 		goto err;
354*053f45beSAndroid Build Coastguard Worker 
355*053f45beSAndroid Build Coastguard Worker 	for (i = 0; i < encl->nr_segments; i++) {
356*053f45beSAndroid Build Coastguard Worker 		struct encl_segment *seg = &encl->segment_tbl[i];
357*053f45beSAndroid Build Coastguard Worker 
358*053f45beSAndroid Build Coastguard Worker 		if (!mrenclave_segment(ctx, encl, seg))
359*053f45beSAndroid Build Coastguard Worker 			goto err;
360*053f45beSAndroid Build Coastguard Worker 	}
361*053f45beSAndroid Build Coastguard Worker 
362*053f45beSAndroid Build Coastguard Worker 	if (!mrenclave_commit(ctx, sigstruct->body.mrenclave))
363*053f45beSAndroid Build Coastguard Worker 		goto err;
364*053f45beSAndroid Build Coastguard Worker 
365*053f45beSAndroid Build Coastguard Worker 	memcpy(&payload.header, &sigstruct->header, sizeof(sigstruct->header));
366*053f45beSAndroid Build Coastguard Worker 	memcpy(&payload.body, &sigstruct->body, sizeof(sigstruct->body));
367*053f45beSAndroid Build Coastguard Worker 
368*053f45beSAndroid Build Coastguard Worker 	SHA256((unsigned char *)&payload, sizeof(payload), digest);
369*053f45beSAndroid Build Coastguard Worker 
370*053f45beSAndroid Build Coastguard Worker 	if (!RSA_sign(NID_sha256, digest, SHA256_DIGEST_LENGTH,
371*053f45beSAndroid Build Coastguard Worker 		      sigstruct->signature, &siglen, key))
372*053f45beSAndroid Build Coastguard Worker 		goto err;
373*053f45beSAndroid Build Coastguard Worker 
374*053f45beSAndroid Build Coastguard Worker 	if (!calc_q1q2(sigstruct->signature, sigstruct->modulus, sigstruct->q1,
375*053f45beSAndroid Build Coastguard Worker 		       sigstruct->q2))
376*053f45beSAndroid Build Coastguard Worker 		goto err;
377*053f45beSAndroid Build Coastguard Worker 
378*053f45beSAndroid Build Coastguard Worker 	/* BE -> LE */
379*053f45beSAndroid Build Coastguard Worker 	reverse_bytes(sigstruct->signature, SGX_MODULUS_SIZE);
380*053f45beSAndroid Build Coastguard Worker 	reverse_bytes(sigstruct->modulus, SGX_MODULUS_SIZE);
381*053f45beSAndroid Build Coastguard Worker 
382*053f45beSAndroid Build Coastguard Worker 	EVP_MD_CTX_destroy(ctx);
383*053f45beSAndroid Build Coastguard Worker 	RSA_free(key);
384*053f45beSAndroid Build Coastguard Worker 	return true;
385*053f45beSAndroid Build Coastguard Worker 
386*053f45beSAndroid Build Coastguard Worker err:
387*053f45beSAndroid Build Coastguard Worker 	EVP_MD_CTX_destroy(ctx);
388*053f45beSAndroid Build Coastguard Worker 	RSA_free(key);
389*053f45beSAndroid Build Coastguard Worker 	return false;
390*053f45beSAndroid Build Coastguard Worker }
391