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