Files
Li, Xun 8a22317709 Linux 2.22 Open Source Gold Release
Upgraded to OpenSSL 3.0.10.
Added interoperable RA-TLS support which follows CCC design.
Enhanced Protect File System performance and added additional dependency
  `libsgx_pthread.a`.
Added the Constant Time instruction Decoder (CTD) into the default AEX-Notify
  mitigation handler in order to prevent the introduction of any additional
  subtle sidechannel leakages within the default handler.
Added Mistletoe 3 mitigations to the IPP Cryptography Library to the AES-ECB,
  AESGCM, and AES-CMAC algorithms. These have been incorporated transparently
  into the `sgx_tcrypto` library.
Resigned all Intel® SGX Architecture Enclaves.
Upgraded Intel SGX Quote Verification Enclave to integrate OpenSSL/SgxSSL 3.0.10.
Added Attestation Library support for Intel(R) TDX Migration TD.
Added Rust wrapper for low-level Quote Generation APIs.
Enabled `SE_TRACE` log in release binary.
Updated Rust QVL wrapper to use native Rust structure for quote verification
  collateral.
Added a limitation in the DCAP QVL to only allow the user to set the QvE load
  policy once.
Fixed bugs.

Signed-off-by: Li, Xun <xun.li@intel.com>
2023-10-24 11:05:23 +08:00

260 lines
6.2 KiB
C++

/**
*
* MIT License
*
* Copyright (c) Open Enclave SDK contributors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE
*
*/
#include "utility.h"
//
// Generate_Key_Pair function:
// type1: RSA
// type2: EC-P384
// currently all hardware independant
//
#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <openssl/ec.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <stdlib.h>
#include <string.h>
#include "sgx_trts.h"
int get_pkey_by_rsa(EVP_PKEY *pk)
{
int res = -1;
EVP_PKEY_CTX *ctx = NULL;
ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
if (ctx == NULL)
return res;
res = EVP_PKEY_keygen_init(ctx);
if (res <= 0)
{
PRINT("keygen_init failed (%d)\n", res);
goto done;
}
res = EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, RSA_3072_PRIVATE_KEY_SIZE);
if (res <= 0)
{
PRINT("set_rsa_kengen_bits failed (%d)\n", res);
goto done;
}
/* Generate key */
res = EVP_PKEY_keygen(ctx, &pk);
if (res <= 0)
{
PRINT("keygen failed (%d)\n", res);
goto done;
}
done:
if (ctx)
EVP_PKEY_CTX_free(ctx);
return res;
}
int get_pkey_by_ec(EVP_PKEY *pk)
{
int res = -1;
EVP_PKEY_CTX *ctx;
ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
if (ctx == NULL)
return res;
res = EVP_PKEY_keygen_init(ctx);
if (res <= 0)
{
PRINT("EC_generate_key failed (%d)\n", res);
goto done;
}
res = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, NID_secp384r1);
if (res <= 0)
{
PRINT("EC_generate_key failed (%d)\n", res);
goto done;
}
/* Generate key */
res = EVP_PKEY_keygen(ctx, &pk);
if (res <= 0)
{
PRINT("EC_generate_key failed (%d)\n", res);
goto done;
}
done:
if (ctx)
EVP_PKEY_CTX_free(ctx);
return res;
}
// actually is generating RSA pair
// hardare independant
sgx_status_t generate_key_pair(
int type,
uint8_t** public_key,
size_t* public_key_size,
uint8_t** private_key,
size_t* private_key_size)
{
sgx_status_t result = SGX_ERROR_UNEXPECTED;
uint8_t* local_public_key = nullptr;
uint8_t* local_private_key = nullptr;
int res = -1;
EVP_PKEY* pkey = nullptr;
BIO* bio = nullptr;
pkey = EVP_PKEY_new();
if (!pkey)
{
PRINT("EVP_PKEY_new failed\n");
result = SGX_ERROR_UNEXPECTED;
goto done;
}
if (type != RSA_TYPE && type != EC_TYPE)
{
type = RSA_TYPE; // by default, we use RSA_TYPE
}
switch(type)
{
case RSA_TYPE:
res = get_pkey_by_rsa(pkey);
break;
case EC_TYPE:
res = get_pkey_by_ec(pkey);
break;
}
if (res <= 0)
{
PRINT("get_pkey failed (%d)\n", res);
result = SGX_ERROR_UNEXPECTED;
goto done;
}
// Allocate memory
local_public_key = (uint8_t*)malloc(RSA_3072_PUBLIC_KEY_SIZE);
if (!local_public_key)
{
PRINT("out-of-memory:calloc(local_public_key failed\n");
result = SGX_ERROR_OUT_OF_EPC;
goto done;
}
memset(local_public_key, 0x00, RSA_3072_PUBLIC_KEY_SIZE);
local_private_key = (uint8_t*)malloc(RSA_3072_PRIVATE_KEY_SIZE);
if (!local_private_key)
{
PRINT("out-of-memory: calloc(local_private_key) failed\n");
result = SGX_ERROR_OUT_OF_EPC;
goto done;
}
memset(local_private_key, 0x00, RSA_3072_PRIVATE_KEY_SIZE);
// Write out the public/private key in PEM format for exchange with
// other enclaves.
bio = BIO_new(BIO_s_mem());
if (!bio)
{
PRINT("BIO_new for local_public_key failed\n");
goto done;
}
res = PEM_write_bio_PUBKEY(bio, pkey);
if (!res)
{
PRINT("PEM_write_bio_PUBKEY failed (%d)\n", res);
goto done;
}
res = BIO_read(bio, local_public_key, RSA_3072_PUBLIC_KEY_SIZE);
if (!res)
{
PRINT("BIO_read public key failed (%d)\n", res);
goto done;
}
BIO_free(bio);
bio = nullptr;
bio = BIO_new(BIO_s_mem());
if (!bio)
{
PRINT("BIO_new for local_public_key failed\n");
goto done;
}
res = PEM_write_bio_PrivateKey(
bio, pkey, nullptr, nullptr, 0, nullptr, nullptr);
if (!res)
{
PRINT("PEM_write_bio_PrivateKey failed (%d)\n", res);
goto done;
}
res = BIO_read(bio, local_private_key, RSA_3072_PRIVATE_KEY_SIZE);
if (!res)
{
PRINT("BIO_read private key failed (%d)\n", res);
goto done;
}
BIO_free(bio);
bio = nullptr;
*public_key = local_public_key;
*private_key = local_private_key;
*public_key_size = strlen(reinterpret_cast<const char *>(local_public_key)) + 1;
*private_key_size = strlen(reinterpret_cast<const char *>(local_private_key)) + 1;
PRINT("public_key_size %d, private_key_size %d\n", *public_key_size, *private_key_size);
result = SGX_SUCCESS;
done:
if (bio)
BIO_free(bio);
if (pkey)
EVP_PKEY_free(pkey); // When this is called, rsa is also freed
if (result != SGX_SUCCESS)
{
if (local_public_key)
free(local_public_key);
if (local_private_key)
free(local_private_key);
}
return result;
}