diff --git a/Assignment 7 - SGX Hands-on/src/enclave/enclave.c b/Assignment 7 - SGX Hands-on/src/enclave/enclave.c new file mode 100644 index 0000000..06a6a36 --- /dev/null +++ b/Assignment 7 - SGX Hands-on/src/enclave/enclave.c @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2011-2018 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include +#include /* vsnprintf */ +#include +#include + +#include "Enclave.h" +#include "Enclave_t.h" +#include +#include +#include + +#ifndef SK_SIZE +#define SK_SIZE SGX_ECP256_KEY_SIZE +#endif + +#ifndef PK_SIZE +#define PK_SIZE 2*SK_SIZE +#endif + +#ifndef SI_SIZE +#define SI_SIZE 2*SK_SIZE +#endif + +const sgx_ec256_public_t authorized[2] = { + { + 0, + 0 + }, + { + 0, + 0 + } +}; + +int get_sealed_size() { + return sgx_calc_sealed_data_size(PK_SIZE, SK_SIZE); +} + +int get_signature_size() { + return SI_SIZE; +} + +int get_public_key_size() { + return PK_SIZE; +} + +int get_private_key_size() { + return SK_SIZE; +} + +static sgx_status_t seal_key_pair(sgx_ec256_private_t *private, sgx_ec256_public_t *public, uint8_t **sealed, uint32_t sealed_size) { + // invalid parameter handling + if((private == NULL) || (public == NULL)) + return SGX_ERROR_INVALID_PARAMETER; + + // allocate temporary buffers on stack + uint8_t pk[PK_SIZE] = {0}; + uint8_t sk[SK_SIZE] = {0}; + + // copy key pair into buffers + memcpy(pk, public->gx, PK_SIZE); + memcpy(sk, private->r, SK_SIZE); + + // calculate needed size + uint32_t size = get_sealed_size(); + if(size > sealed_size) { + return SGX_ERROR_INVALID_PARAMETER; + } + + // seal keypair + return sgx_seal_data(PK_SIZE, (const uint8_t *)pk, SK_SIZE, (const uint8_t *)sk, size, (sgx_sealed_data_t *) *sealed); +} + +static sgx_status_t unseal_key_pair(const uint8_t *sealed, sgx_ec256_private_t *private, sgx_ec256_public_t *public) { + // invalid parameter handling + if(sealed == NULL) { + return SGX_ERROR_INVALID_PARAMETER; + } + + // allocate temporary buffers on stack + uint8_t pk[PK_SIZE] = {0}; + uint8_t sk[SK_SIZE] = {0}; + + // calculate public_key size and return error for unexpected results + uint32_t pk_size = sgx_get_add_mac_txt_len((const sgx_sealed_data_t *)sealed); + uint32_t sk_size = sgx_get_encrypt_txt_len((const sgx_sealed_data_t *)sealed); + if ((pk_size != PK_SIZE) || (sk_size != SK_SIZE)) { + return SGX_ERROR_UNEXPECTED; + } + + // unseal ecc key pair + sgx_status_t status = sgx_unseal_data((const sgx_sealed_data_t *)sealed, pk, &pk_size, sk, &sk_size); + if (status != SGX_SUCCESS) { + return status; + } + + // copy buffers into key structs + if(public != NULL) { + memcpy(public->gx, pk, PK_SIZE); + } + if (private != NULL) { + memcpy(private->r, sk, SK_SIZE); + } + + // return success + return status; +} + +sgx_status_t get_public_key(const uint8_t *sealed, uint32_t sealed_size, uint8_t *gx, uint32_t gx_size, uint8_t *gy, uint32_t gy_size) { + // invalid parameter handling + if((sealed == NULL) || (sealed_size == 0)) { + return SGX_ERROR_INVALID_PARAMETER; + } + + // unseal public key + sgx_status_t status; + sgx_ec256_public_t public; + if((status = unseal_key_pair(sealed, NULL, &public)) != SGX_SUCCESS) { + return status; + } + + // copy public key into return buffers + if((gx != NULL) && (gy != NULL)) { + memcpy(gx, public.gx, SK_SIZE); + memcpy(gy, public.gy, SK_SIZE); + } + + // return success + return status; +} + +sgx_status_t sign_firmware(const uint8_t *data, uint32_t data_size, uint8_t *sealed, uint32_t sealed_size, uint8_t *signature, uint32_t signature_size) { + // invalid parameter handling + if((data == NULL) || (data_size == 0)) { + return SGX_ERROR_INVALID_PARAMETER; + } else if((sealed == NULL) || (sealed_size == 0)) { + return SGX_ERROR_INVALID_PARAMETER; + } + + // declare need structures + sgx_ecc_state_handle_t ecc_handle; + sgx_ec256_private_t private; + sgx_ec256_public_t public; + + // open ecc handle + sgx_status_t status; + if((status = sgx_ecc256_open_context(&ecc_handle)) != SGX_SUCCESS) { + return status; + } + + // try unseal keypair + sgx_status_t seal_status; + if(seal_status = unseal_key_pair(sealed, &private, NULL) != SGX_SUCCESS) { + if((status = sgx_ecc256_create_key_pair(&private, &public, ecc_handle)) != SGX_SUCCESS) { + sgx_ecc256_close_context(ecc_handle); + return status; + } + } + + // create signature + sgx_ec256_signature_t ecc_signature; + if((status = sgx_ecdsa_sign(data, data_size, &private, &ecc_signature, ecc_handle)) != SGX_SUCCESS) { + sgx_ecc256_close_context(ecc_handle); + return status; + } + + // TODO: possible wrong endianess for other programms + // copy signature to return buffer + if((signature == NULL) || (signature_size == 0)) { + sgx_ecc256_close_context(ecc_handle); + return SGX_ERROR_INVALID_PARAMETER; + } + memcpy(signature, ecc_signature.x, SI_SIZE); + + // seal the key + if((seal_status != SGX_SUCCESS) && (sealed != NULL)) { + seal_status = seal_key_pair(&private, &public, &sealed, sealed_size); + } + + // close ecc handle and return success + sgx_ecc256_close_context(ecc_handle); + return seal_status; +} + +sgx_status_t verify_firmware(const uint8_t *data, uint32_t data_size, const uint8_t *sealed, uint32_t sealed_size, const uint8_t *public_key, uint32_t public_key_size, const uint8_t *signature, uint32_t signature_size) { + // invalid parameter handling + if((data == NULL) || (data_size == 0)) { + return SGX_ERROR_INVALID_PARAMETER; + } else if(((sealed == NULL) || (sealed_size == 0)) && ((public_key == NULL) || (public_key_size == 0))) { + return SGX_ERROR_INVALID_PARAMETER; + } else if((sealed != NULL) && (public_key != NULL)) { + return SGX_ERROR_INVALID_PARAMETER; + } else if((signature == NULL) || (signature_size == 0)) { + return SGX_ERROR_INVALID_PARAMETER; + } + + // declare need structures + sgx_ec256_signature_t ecc_signature; + sgx_ecc_state_handle_t ecc_handle; + sgx_ec256_public_t public; + + // invalid signature + if(signature_size > SI_SIZE) { + return SGX_ERROR_INVALID_PARAMETER; + } + + // open ecc handle + sgx_status_t status; + if((status = sgx_ecc256_open_context(&ecc_handle)) != SGX_SUCCESS) { + return status; + } + + // copy signature into struct + memcpy(ecc_signature.x, signature, SI_SIZE); + + // verify signature from staff or enclave + if(public_key != NULL) { + // invalid public key + if(public_key_size != PK_SIZE) { + sgx_ecc256_close_context(ecc_handle); + return SGX_ERROR_INVALID_PARAMETER; + } + + // copy public key into struct + memcpy(public.gx, public_key, PK_SIZE); + } else { + // unseal public key + if(unseal_key_pair(sealed, NULL, &public) != SGX_SUCCESS) { + sgx_ecc256_close_context(ecc_handle); + return SGX_ERROR_UNEXPECTED; + } + } + + // verify signature + uint8_t result; + sgx_status_t verification_status = sgx_ecdsa_verify(data, data_size, (const sgx_ec256_public_t *)&public, (const sgx_ec256_signature_t *)&ecc_signature, &result, ecc_handle); + + // handle failed verification process + if(verification_status != SGX_SUCCESS) { + result = verification_status; + } + + // close handle and return result + sgx_ecc256_close_context(ecc_handle); + return result; +} \ No newline at end of file