12adcba79SJarkko Sakkinen // SPDX-License-Identifier: GPL-2.0 22adcba79SJarkko Sakkinen /* Copyright(c) 2016-20 Intel Corporation. */ 32adcba79SJarkko Sakkinen 42adcba79SJarkko Sakkinen #define _GNU_SOURCE 52adcba79SJarkko Sakkinen #include <assert.h> 62adcba79SJarkko Sakkinen #include <getopt.h> 72adcba79SJarkko Sakkinen #include <stdbool.h> 82adcba79SJarkko Sakkinen #include <stdint.h> 92adcba79SJarkko Sakkinen #include <stdio.h> 102adcba79SJarkko Sakkinen #include <stdlib.h> 112adcba79SJarkko Sakkinen #include <string.h> 122adcba79SJarkko Sakkinen #include <sys/stat.h> 132adcba79SJarkko Sakkinen #include <sys/types.h> 142adcba79SJarkko Sakkinen #include <unistd.h> 152adcba79SJarkko Sakkinen #include <openssl/err.h> 162adcba79SJarkko Sakkinen #include <openssl/pem.h> 172adcba79SJarkko Sakkinen #include "defines.h" 182adcba79SJarkko Sakkinen #include "main.h" 192adcba79SJarkko Sakkinen 20*5f4d1fd5SKristen Carlson Accardi /* 21*5f4d1fd5SKristen Carlson Accardi * FIXME: OpenSSL 3.0 has deprecated some functions. For now just ignore 22*5f4d1fd5SKristen Carlson Accardi * the warnings. 23*5f4d1fd5SKristen Carlson Accardi */ 24*5f4d1fd5SKristen Carlson Accardi #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 25*5f4d1fd5SKristen Carlson Accardi 262adcba79SJarkko Sakkinen struct q1q2_ctx { 272adcba79SJarkko Sakkinen BN_CTX *bn_ctx; 282adcba79SJarkko Sakkinen BIGNUM *m; 292adcba79SJarkko Sakkinen BIGNUM *s; 302adcba79SJarkko Sakkinen BIGNUM *q1; 312adcba79SJarkko Sakkinen BIGNUM *qr; 322adcba79SJarkko Sakkinen BIGNUM *q2; 332adcba79SJarkko Sakkinen }; 342adcba79SJarkko Sakkinen 352adcba79SJarkko Sakkinen static void free_q1q2_ctx(struct q1q2_ctx *ctx) 362adcba79SJarkko Sakkinen { 372adcba79SJarkko Sakkinen BN_CTX_free(ctx->bn_ctx); 382adcba79SJarkko Sakkinen BN_free(ctx->m); 392adcba79SJarkko Sakkinen BN_free(ctx->s); 402adcba79SJarkko Sakkinen BN_free(ctx->q1); 412adcba79SJarkko Sakkinen BN_free(ctx->qr); 422adcba79SJarkko Sakkinen BN_free(ctx->q2); 432adcba79SJarkko Sakkinen } 442adcba79SJarkko Sakkinen 452adcba79SJarkko Sakkinen static bool alloc_q1q2_ctx(const uint8_t *s, const uint8_t *m, 462adcba79SJarkko Sakkinen struct q1q2_ctx *ctx) 472adcba79SJarkko Sakkinen { 482adcba79SJarkko Sakkinen ctx->bn_ctx = BN_CTX_new(); 492adcba79SJarkko Sakkinen ctx->s = BN_bin2bn(s, SGX_MODULUS_SIZE, NULL); 502adcba79SJarkko Sakkinen ctx->m = BN_bin2bn(m, SGX_MODULUS_SIZE, NULL); 512adcba79SJarkko Sakkinen ctx->q1 = BN_new(); 522adcba79SJarkko Sakkinen ctx->qr = BN_new(); 532adcba79SJarkko Sakkinen ctx->q2 = BN_new(); 542adcba79SJarkko Sakkinen 552adcba79SJarkko Sakkinen if (!ctx->bn_ctx || !ctx->s || !ctx->m || !ctx->q1 || !ctx->qr || 562adcba79SJarkko Sakkinen !ctx->q2) { 572adcba79SJarkko Sakkinen free_q1q2_ctx(ctx); 582adcba79SJarkko Sakkinen return false; 592adcba79SJarkko Sakkinen } 602adcba79SJarkko Sakkinen 612adcba79SJarkko Sakkinen return true; 622adcba79SJarkko Sakkinen } 632adcba79SJarkko Sakkinen 64567c3904STianjia Zhang static void reverse_bytes(void *data, int length) 65567c3904STianjia Zhang { 66567c3904STianjia Zhang int i = 0; 67567c3904STianjia Zhang int j = length - 1; 68567c3904STianjia Zhang uint8_t temp; 69567c3904STianjia Zhang uint8_t *ptr = data; 70567c3904STianjia Zhang 71567c3904STianjia Zhang while (i < j) { 72567c3904STianjia Zhang temp = ptr[i]; 73567c3904STianjia Zhang ptr[i] = ptr[j]; 74567c3904STianjia Zhang ptr[j] = temp; 75567c3904STianjia Zhang i++; 76567c3904STianjia Zhang j--; 77567c3904STianjia Zhang } 78567c3904STianjia Zhang } 79567c3904STianjia Zhang 802adcba79SJarkko Sakkinen static bool calc_q1q2(const uint8_t *s, const uint8_t *m, uint8_t *q1, 812adcba79SJarkko Sakkinen uint8_t *q2) 822adcba79SJarkko Sakkinen { 832adcba79SJarkko Sakkinen struct q1q2_ctx ctx; 84567c3904STianjia Zhang int len; 852adcba79SJarkko Sakkinen 862adcba79SJarkko Sakkinen if (!alloc_q1q2_ctx(s, m, &ctx)) { 872adcba79SJarkko Sakkinen fprintf(stderr, "Not enough memory for Q1Q2 calculation\n"); 882adcba79SJarkko Sakkinen return false; 892adcba79SJarkko Sakkinen } 902adcba79SJarkko Sakkinen 912adcba79SJarkko Sakkinen if (!BN_mul(ctx.q1, ctx.s, ctx.s, ctx.bn_ctx)) 922adcba79SJarkko Sakkinen goto out; 932adcba79SJarkko Sakkinen 942adcba79SJarkko Sakkinen if (!BN_div(ctx.q1, ctx.qr, ctx.q1, ctx.m, ctx.bn_ctx)) 952adcba79SJarkko Sakkinen goto out; 962adcba79SJarkko Sakkinen 972adcba79SJarkko Sakkinen if (BN_num_bytes(ctx.q1) > SGX_MODULUS_SIZE) { 982adcba79SJarkko Sakkinen fprintf(stderr, "Too large Q1 %d bytes\n", 992adcba79SJarkko Sakkinen BN_num_bytes(ctx.q1)); 1002adcba79SJarkko Sakkinen goto out; 1012adcba79SJarkko Sakkinen } 1022adcba79SJarkko Sakkinen 1032adcba79SJarkko Sakkinen if (!BN_mul(ctx.q2, ctx.s, ctx.qr, ctx.bn_ctx)) 1042adcba79SJarkko Sakkinen goto out; 1052adcba79SJarkko Sakkinen 1062adcba79SJarkko Sakkinen if (!BN_div(ctx.q2, NULL, ctx.q2, ctx.m, ctx.bn_ctx)) 1072adcba79SJarkko Sakkinen goto out; 1082adcba79SJarkko Sakkinen 1092adcba79SJarkko Sakkinen if (BN_num_bytes(ctx.q2) > SGX_MODULUS_SIZE) { 1102adcba79SJarkko Sakkinen fprintf(stderr, "Too large Q2 %d bytes\n", 1112adcba79SJarkko Sakkinen BN_num_bytes(ctx.q2)); 1122adcba79SJarkko Sakkinen goto out; 1132adcba79SJarkko Sakkinen } 1142adcba79SJarkko Sakkinen 115567c3904STianjia Zhang len = BN_bn2bin(ctx.q1, q1); 116567c3904STianjia Zhang reverse_bytes(q1, len); 117567c3904STianjia Zhang len = BN_bn2bin(ctx.q2, q2); 118567c3904STianjia Zhang reverse_bytes(q2, len); 1192adcba79SJarkko Sakkinen 1202adcba79SJarkko Sakkinen free_q1q2_ctx(&ctx); 1212adcba79SJarkko Sakkinen return true; 1222adcba79SJarkko Sakkinen out: 1232adcba79SJarkko Sakkinen free_q1q2_ctx(&ctx); 1242adcba79SJarkko Sakkinen return false; 1252adcba79SJarkko Sakkinen } 1262adcba79SJarkko Sakkinen 1272adcba79SJarkko Sakkinen struct sgx_sigstruct_payload { 1282adcba79SJarkko Sakkinen struct sgx_sigstruct_header header; 1292adcba79SJarkko Sakkinen struct sgx_sigstruct_body body; 1302adcba79SJarkko Sakkinen }; 1312adcba79SJarkko Sakkinen 1322adcba79SJarkko Sakkinen static bool check_crypto_errors(void) 1332adcba79SJarkko Sakkinen { 1342adcba79SJarkko Sakkinen int err; 1352adcba79SJarkko Sakkinen bool had_errors = false; 1362adcba79SJarkko Sakkinen const char *filename; 1372adcba79SJarkko Sakkinen int line; 1382adcba79SJarkko Sakkinen char str[256]; 1392adcba79SJarkko Sakkinen 1402adcba79SJarkko Sakkinen for ( ; ; ) { 1412adcba79SJarkko Sakkinen if (ERR_peek_error() == 0) 1422adcba79SJarkko Sakkinen break; 1432adcba79SJarkko Sakkinen 1442adcba79SJarkko Sakkinen had_errors = true; 1452adcba79SJarkko Sakkinen err = ERR_get_error_line(&filename, &line); 1462adcba79SJarkko Sakkinen ERR_error_string_n(err, str, sizeof(str)); 1472adcba79SJarkko Sakkinen fprintf(stderr, "crypto: %s: %s:%d\n", str, filename, line); 1482adcba79SJarkko Sakkinen } 1492adcba79SJarkko Sakkinen 1502adcba79SJarkko Sakkinen return had_errors; 1512adcba79SJarkko Sakkinen } 1522adcba79SJarkko Sakkinen 1532adcba79SJarkko Sakkinen static inline const BIGNUM *get_modulus(RSA *key) 1542adcba79SJarkko Sakkinen { 1552adcba79SJarkko Sakkinen const BIGNUM *n; 1562adcba79SJarkko Sakkinen 1572adcba79SJarkko Sakkinen RSA_get0_key(key, &n, NULL, NULL); 1582adcba79SJarkko Sakkinen return n; 1592adcba79SJarkko Sakkinen } 1602adcba79SJarkko Sakkinen 1612adcba79SJarkko Sakkinen static RSA *gen_sign_key(void) 1622adcba79SJarkko Sakkinen { 1630eaa8d15SJarkko Sakkinen unsigned long sign_key_length; 1640eaa8d15SJarkko Sakkinen BIO *bio; 1652adcba79SJarkko Sakkinen RSA *key; 1662adcba79SJarkko Sakkinen 1670eaa8d15SJarkko Sakkinen sign_key_length = (unsigned long)&sign_key_end - 1680eaa8d15SJarkko Sakkinen (unsigned long)&sign_key; 1692adcba79SJarkko Sakkinen 1700eaa8d15SJarkko Sakkinen bio = BIO_new_mem_buf(&sign_key, sign_key_length); 1710eaa8d15SJarkko Sakkinen if (!bio) 1720eaa8d15SJarkko Sakkinen return NULL; 1732adcba79SJarkko Sakkinen 1740eaa8d15SJarkko Sakkinen key = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL); 1750eaa8d15SJarkko Sakkinen BIO_free(bio); 1762adcba79SJarkko Sakkinen 1772adcba79SJarkko Sakkinen return key; 1782adcba79SJarkko Sakkinen } 1792adcba79SJarkko Sakkinen 1802adcba79SJarkko Sakkinen enum mrtags { 1812adcba79SJarkko Sakkinen MRECREATE = 0x0045544145524345, 1822adcba79SJarkko Sakkinen MREADD = 0x0000000044444145, 1832adcba79SJarkko Sakkinen MREEXTEND = 0x00444E4554584545, 1842adcba79SJarkko Sakkinen }; 1852adcba79SJarkko Sakkinen 1862adcba79SJarkko Sakkinen static bool mrenclave_update(EVP_MD_CTX *ctx, const void *data) 1872adcba79SJarkko Sakkinen { 1882adcba79SJarkko Sakkinen if (!EVP_DigestUpdate(ctx, data, 64)) { 1892adcba79SJarkko Sakkinen fprintf(stderr, "digest update failed\n"); 1902adcba79SJarkko Sakkinen return false; 1912adcba79SJarkko Sakkinen } 1922adcba79SJarkko Sakkinen 1932adcba79SJarkko Sakkinen return true; 1942adcba79SJarkko Sakkinen } 1952adcba79SJarkko Sakkinen 1962adcba79SJarkko Sakkinen static bool mrenclave_commit(EVP_MD_CTX *ctx, uint8_t *mrenclave) 1972adcba79SJarkko Sakkinen { 1982adcba79SJarkko Sakkinen unsigned int size; 1992adcba79SJarkko Sakkinen 2002adcba79SJarkko Sakkinen if (!EVP_DigestFinal_ex(ctx, (unsigned char *)mrenclave, &size)) { 2012adcba79SJarkko Sakkinen fprintf(stderr, "digest commit failed\n"); 2022adcba79SJarkko Sakkinen return false; 2032adcba79SJarkko Sakkinen } 2042adcba79SJarkko Sakkinen 2052adcba79SJarkko Sakkinen if (size != 32) { 2062adcba79SJarkko Sakkinen fprintf(stderr, "invalid digest size = %u\n", size); 2072adcba79SJarkko Sakkinen return false; 2082adcba79SJarkko Sakkinen } 2092adcba79SJarkko Sakkinen 2102adcba79SJarkko Sakkinen return true; 2112adcba79SJarkko Sakkinen } 2122adcba79SJarkko Sakkinen 2132adcba79SJarkko Sakkinen struct mrecreate { 2142adcba79SJarkko Sakkinen uint64_t tag; 2152adcba79SJarkko Sakkinen uint32_t ssaframesize; 2162adcba79SJarkko Sakkinen uint64_t size; 2172adcba79SJarkko Sakkinen uint8_t reserved[44]; 2182adcba79SJarkko Sakkinen } __attribute__((__packed__)); 2192adcba79SJarkko Sakkinen 2202adcba79SJarkko Sakkinen 2212adcba79SJarkko Sakkinen static bool mrenclave_ecreate(EVP_MD_CTX *ctx, uint64_t blob_size) 2222adcba79SJarkko Sakkinen { 2232adcba79SJarkko Sakkinen struct mrecreate mrecreate; 2242adcba79SJarkko Sakkinen uint64_t encl_size; 2252adcba79SJarkko Sakkinen 2262adcba79SJarkko Sakkinen for (encl_size = 0x1000; encl_size < blob_size; ) 2272adcba79SJarkko Sakkinen encl_size <<= 1; 2282adcba79SJarkko Sakkinen 2292adcba79SJarkko Sakkinen memset(&mrecreate, 0, sizeof(mrecreate)); 2302adcba79SJarkko Sakkinen mrecreate.tag = MRECREATE; 2312adcba79SJarkko Sakkinen mrecreate.ssaframesize = 1; 2322adcba79SJarkko Sakkinen mrecreate.size = encl_size; 2332adcba79SJarkko Sakkinen 2342adcba79SJarkko Sakkinen if (!EVP_DigestInit_ex(ctx, EVP_sha256(), NULL)) 2352adcba79SJarkko Sakkinen return false; 2362adcba79SJarkko Sakkinen 2372adcba79SJarkko Sakkinen return mrenclave_update(ctx, &mrecreate); 2382adcba79SJarkko Sakkinen } 2392adcba79SJarkko Sakkinen 2402adcba79SJarkko Sakkinen struct mreadd { 2412adcba79SJarkko Sakkinen uint64_t tag; 2422adcba79SJarkko Sakkinen uint64_t offset; 2432adcba79SJarkko Sakkinen uint64_t flags; /* SECINFO flags */ 2442adcba79SJarkko Sakkinen uint8_t reserved[40]; 2452adcba79SJarkko Sakkinen } __attribute__((__packed__)); 2462adcba79SJarkko Sakkinen 2472adcba79SJarkko Sakkinen static bool mrenclave_eadd(EVP_MD_CTX *ctx, uint64_t offset, uint64_t flags) 2482adcba79SJarkko Sakkinen { 2492adcba79SJarkko Sakkinen struct mreadd mreadd; 2502adcba79SJarkko Sakkinen 2512adcba79SJarkko Sakkinen memset(&mreadd, 0, sizeof(mreadd)); 2522adcba79SJarkko Sakkinen mreadd.tag = MREADD; 2532adcba79SJarkko Sakkinen mreadd.offset = offset; 2542adcba79SJarkko Sakkinen mreadd.flags = flags; 2552adcba79SJarkko Sakkinen 2562adcba79SJarkko Sakkinen return mrenclave_update(ctx, &mreadd); 2572adcba79SJarkko Sakkinen } 2582adcba79SJarkko Sakkinen 2592adcba79SJarkko Sakkinen struct mreextend { 2602adcba79SJarkko Sakkinen uint64_t tag; 2612adcba79SJarkko Sakkinen uint64_t offset; 2622adcba79SJarkko Sakkinen uint8_t reserved[48]; 2632adcba79SJarkko Sakkinen } __attribute__((__packed__)); 2642adcba79SJarkko Sakkinen 2652adcba79SJarkko Sakkinen static bool mrenclave_eextend(EVP_MD_CTX *ctx, uint64_t offset, 2662adcba79SJarkko Sakkinen const uint8_t *data) 2672adcba79SJarkko Sakkinen { 2682adcba79SJarkko Sakkinen struct mreextend mreextend; 2692adcba79SJarkko Sakkinen int i; 2702adcba79SJarkko Sakkinen 2712adcba79SJarkko Sakkinen for (i = 0; i < 0x1000; i += 0x100) { 2722adcba79SJarkko Sakkinen memset(&mreextend, 0, sizeof(mreextend)); 2732adcba79SJarkko Sakkinen mreextend.tag = MREEXTEND; 2742adcba79SJarkko Sakkinen mreextend.offset = offset + i; 2752adcba79SJarkko Sakkinen 2762adcba79SJarkko Sakkinen if (!mrenclave_update(ctx, &mreextend)) 2772adcba79SJarkko Sakkinen return false; 2782adcba79SJarkko Sakkinen 2792adcba79SJarkko Sakkinen if (!mrenclave_update(ctx, &data[i + 0x00])) 2802adcba79SJarkko Sakkinen return false; 2812adcba79SJarkko Sakkinen 2822adcba79SJarkko Sakkinen if (!mrenclave_update(ctx, &data[i + 0x40])) 2832adcba79SJarkko Sakkinen return false; 2842adcba79SJarkko Sakkinen 2852adcba79SJarkko Sakkinen if (!mrenclave_update(ctx, &data[i + 0x80])) 2862adcba79SJarkko Sakkinen return false; 2872adcba79SJarkko Sakkinen 2882adcba79SJarkko Sakkinen if (!mrenclave_update(ctx, &data[i + 0xC0])) 2892adcba79SJarkko Sakkinen return false; 2902adcba79SJarkko Sakkinen } 2912adcba79SJarkko Sakkinen 2922adcba79SJarkko Sakkinen return true; 2932adcba79SJarkko Sakkinen } 2942adcba79SJarkko Sakkinen 2952adcba79SJarkko Sakkinen static bool mrenclave_segment(EVP_MD_CTX *ctx, struct encl *encl, 2962adcba79SJarkko Sakkinen struct encl_segment *seg) 2972adcba79SJarkko Sakkinen { 29839f62536SJarkko Sakkinen uint64_t end = seg->size; 2992adcba79SJarkko Sakkinen uint64_t offset; 3002adcba79SJarkko Sakkinen 30139f62536SJarkko Sakkinen for (offset = 0; offset < end; offset += PAGE_SIZE) { 30239f62536SJarkko Sakkinen if (!mrenclave_eadd(ctx, seg->offset + offset, seg->flags)) 3032adcba79SJarkko Sakkinen return false; 3042adcba79SJarkko Sakkinen 3055f0ce664SJarkko Sakkinen if (seg->measure) { 30639f62536SJarkko Sakkinen if (!mrenclave_eextend(ctx, seg->offset + offset, seg->src + offset)) 3072adcba79SJarkko Sakkinen return false; 3082adcba79SJarkko Sakkinen } 3095f0ce664SJarkko Sakkinen } 3102adcba79SJarkko Sakkinen 3112adcba79SJarkko Sakkinen return true; 3122adcba79SJarkko Sakkinen } 3132adcba79SJarkko Sakkinen 3142adcba79SJarkko Sakkinen bool encl_measure(struct encl *encl) 3152adcba79SJarkko Sakkinen { 3162adcba79SJarkko Sakkinen uint64_t header1[2] = {0x000000E100000006, 0x0000000000010000}; 3172adcba79SJarkko Sakkinen uint64_t header2[2] = {0x0000006000000101, 0x0000000100000060}; 3182adcba79SJarkko Sakkinen struct sgx_sigstruct *sigstruct = &encl->sigstruct; 3192adcba79SJarkko Sakkinen struct sgx_sigstruct_payload payload; 3202adcba79SJarkko Sakkinen uint8_t digest[SHA256_DIGEST_LENGTH]; 3212adcba79SJarkko Sakkinen unsigned int siglen; 3222adcba79SJarkko Sakkinen RSA *key = NULL; 3232adcba79SJarkko Sakkinen EVP_MD_CTX *ctx; 3242adcba79SJarkko Sakkinen int i; 3252adcba79SJarkko Sakkinen 3262adcba79SJarkko Sakkinen memset(sigstruct, 0, sizeof(*sigstruct)); 3272adcba79SJarkko Sakkinen 3282adcba79SJarkko Sakkinen sigstruct->header.header1[0] = header1[0]; 3292adcba79SJarkko Sakkinen sigstruct->header.header1[1] = header1[1]; 3302adcba79SJarkko Sakkinen sigstruct->header.header2[0] = header2[0]; 3312adcba79SJarkko Sakkinen sigstruct->header.header2[1] = header2[1]; 3322adcba79SJarkko Sakkinen sigstruct->exponent = 3; 3332adcba79SJarkko Sakkinen sigstruct->body.attributes = SGX_ATTR_MODE64BIT; 3342adcba79SJarkko Sakkinen sigstruct->body.xfrm = 3; 3352adcba79SJarkko Sakkinen 3362adcba79SJarkko Sakkinen /* sanity check */ 3372adcba79SJarkko Sakkinen if (check_crypto_errors()) 3382adcba79SJarkko Sakkinen goto err; 3392adcba79SJarkko Sakkinen 3402adcba79SJarkko Sakkinen key = gen_sign_key(); 3410eaa8d15SJarkko Sakkinen if (!key) { 3420eaa8d15SJarkko Sakkinen ERR_print_errors_fp(stdout); 3432adcba79SJarkko Sakkinen goto err; 3440eaa8d15SJarkko Sakkinen } 3452adcba79SJarkko Sakkinen 3462adcba79SJarkko Sakkinen BN_bn2bin(get_modulus(key), sigstruct->modulus); 3472adcba79SJarkko Sakkinen 3482adcba79SJarkko Sakkinen ctx = EVP_MD_CTX_create(); 3492adcba79SJarkko Sakkinen if (!ctx) 3502adcba79SJarkko Sakkinen goto err; 3512adcba79SJarkko Sakkinen 3522adcba79SJarkko Sakkinen if (!mrenclave_ecreate(ctx, encl->src_size)) 3532adcba79SJarkko Sakkinen goto err; 3542adcba79SJarkko Sakkinen 3552adcba79SJarkko Sakkinen for (i = 0; i < encl->nr_segments; i++) { 3562adcba79SJarkko Sakkinen struct encl_segment *seg = &encl->segment_tbl[i]; 3572adcba79SJarkko Sakkinen 3582adcba79SJarkko Sakkinen if (!mrenclave_segment(ctx, encl, seg)) 3592adcba79SJarkko Sakkinen goto err; 3602adcba79SJarkko Sakkinen } 3612adcba79SJarkko Sakkinen 3622adcba79SJarkko Sakkinen if (!mrenclave_commit(ctx, sigstruct->body.mrenclave)) 3632adcba79SJarkko Sakkinen goto err; 3642adcba79SJarkko Sakkinen 3652adcba79SJarkko Sakkinen memcpy(&payload.header, &sigstruct->header, sizeof(sigstruct->header)); 3662adcba79SJarkko Sakkinen memcpy(&payload.body, &sigstruct->body, sizeof(sigstruct->body)); 3672adcba79SJarkko Sakkinen 3682adcba79SJarkko Sakkinen SHA256((unsigned char *)&payload, sizeof(payload), digest); 3692adcba79SJarkko Sakkinen 3702adcba79SJarkko Sakkinen if (!RSA_sign(NID_sha256, digest, SHA256_DIGEST_LENGTH, 3712adcba79SJarkko Sakkinen sigstruct->signature, &siglen, key)) 3722adcba79SJarkko Sakkinen goto err; 3732adcba79SJarkko Sakkinen 3742adcba79SJarkko Sakkinen if (!calc_q1q2(sigstruct->signature, sigstruct->modulus, sigstruct->q1, 3752adcba79SJarkko Sakkinen sigstruct->q2)) 3762adcba79SJarkko Sakkinen goto err; 3772adcba79SJarkko Sakkinen 3782adcba79SJarkko Sakkinen /* BE -> LE */ 3792adcba79SJarkko Sakkinen reverse_bytes(sigstruct->signature, SGX_MODULUS_SIZE); 3802adcba79SJarkko Sakkinen reverse_bytes(sigstruct->modulus, SGX_MODULUS_SIZE); 3812adcba79SJarkko Sakkinen 3822adcba79SJarkko Sakkinen EVP_MD_CTX_destroy(ctx); 3832adcba79SJarkko Sakkinen RSA_free(key); 3842adcba79SJarkko Sakkinen return true; 3852adcba79SJarkko Sakkinen 3862adcba79SJarkko Sakkinen err: 3872adcba79SJarkko Sakkinen EVP_MD_CTX_destroy(ctx); 3882adcba79SJarkko Sakkinen RSA_free(key); 3892adcba79SJarkko Sakkinen return false; 3902adcba79SJarkko Sakkinen } 391