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