Example #1
0
inline std::vector<uint8_t> udg::crypto::seal_data(const uint8_t* data,
        uint32_t len) {

	uint32_t out_size = sgx_calc_sealed_data_size(0, len);

	std::vector<uint8_t> out;
	out.resize(out_size);

	auto res = sgx_seal_data(0, nullptr, len, data, out_size, (sgx_sealed_data_t*)(&out[0]));

	if (res != SGX_SUCCESS) {
		throw udg::crypto::data_integrity_exception();
	}

	return out;

}
Example #2
0
void ecall_test_seal_unseal(){
    migrate_log("[TEST] [SEAL UNSEAL]\n");
    int ret;
    int secretValue = 1337;
    uint32_t sealed_data_size = sgx_calc_sealed_data_size(0, sizeof(int));
    void* sealed_data = malloc(sealed_data_size);

    ret = sgx_seal_migratable_data(0, NULL,sizeof(int),(uint8_t*)&secretValue,
            sealed_data_size, (sgx_sealed_data_t*)sealed_data);

    migrate_log("Sealed blob with ret code %x\n", ret);

    int unsealed_value;
    uint32_t unsealed_size = sizeof(int);
    ret = sgx_unseal_migratable_data((sgx_sealed_data_t*) sealed_data, NULL, 0, (uint8_t*)&unsealed_value, &unsealed_size);
    migrate_log("Unsealed blob with ret code %x\n", ret);
    migrate_log("Sealed value was %u and unsealed was %u\n", secretValue, unsealed_value);
    if(secretValue == unsealed_value){
        migrate_log("[TEST] [SEAL UNSEAL] SUCCESSFULL\n");
    } else {
        migrate_log("[TEST] [SEAL UNSEAL] ERROR\n");
    }
}
Example #3
0
extern "C" sgx_status_t sgx_mac_aadata_ex(const uint16_t key_policy,
                                            const sgx_attributes_t attribute_mask,
                                            const sgx_misc_select_t misc_mask,
                                            const uint32_t additional_MACtext_length,
                                            const uint8_t *p_additional_MACtext,
                                            const uint32_t sealed_data_size,
                                            sgx_sealed_data_t *p_sealed_data)
{
    sgx_status_t err = SGX_ERROR_UNEXPECTED;
    sgx_report_t report;
    sgx_key_id_t keyID;
    sgx_key_request_t tmp_key_request;
    uint8_t payload_iv[SGX_SEAL_IV_SIZE];
    memset(&payload_iv, 0, sizeof(payload_iv));

    uint32_t sealedDataSize = sgx_calc_sealed_data_size(additional_MACtext_length, 0);
    // Check for overflow
    if (sealedDataSize == UINT32_MAX)
    {
        return SGX_ERROR_INVALID_PARAMETER;
    }

    //
    // Check parameters
    //
    // check key_request->key_policy reserved bits are not set and one of policy bits are set
    if ((key_policy & ~(SGX_KEYPOLICY_MRENCLAVE | SGX_KEYPOLICY_MRSIGNER)) ||
        ((key_policy & (SGX_KEYPOLICY_MRENCLAVE | SGX_KEYPOLICY_MRSIGNER)) == 0))
    {
        return SGX_ERROR_INVALID_PARAMETER;
    }
    if ((attribute_mask.flags & 0x3) != 0x3)
    {
        return SGX_ERROR_INVALID_PARAMETER;
    }
    // The AAD must be provided
    if ((additional_MACtext_length == 0) || (p_additional_MACtext == NULL))
    {
        return SGX_ERROR_INVALID_PARAMETER;
    }
    // Ensure AAD does not cross enclave boundary
    if (!(sgx_is_within_enclave(p_additional_MACtext, additional_MACtext_length) ||
        sgx_is_outside_enclave(p_additional_MACtext, additional_MACtext_length)))
    {
        return SGX_ERROR_INVALID_PARAMETER;
    }
    // Ensure sealed data blob is within an enclave during the sealing process
    if ((p_sealed_data == NULL) || (!sgx_is_within_enclave(p_sealed_data, sealed_data_size)))
    {
        return SGX_ERROR_INVALID_PARAMETER;
    }
    if (sealedDataSize != sealed_data_size)
    {
        return SGX_ERROR_INVALID_PARAMETER;
    }
    memset(&report, 0, sizeof(sgx_report_t));
    memset(p_sealed_data, 0, sealedDataSize);
    memset(&keyID, 0, sizeof(sgx_key_id_t));
    memset(&tmp_key_request, 0, sizeof(sgx_key_request_t));

    // Get the report to obtain isv_svn and cpu_svn
    err = sgx_create_report(NULL, NULL, &report);
    if (err != SGX_SUCCESS)
    {
        goto clear_return;
    }

    // Get a random number to populate the key_id of the key_request
    err = sgx_read_rand(reinterpret_cast<uint8_t *>(&keyID), sizeof(sgx_key_id_t));
    if (err != SGX_SUCCESS)
    {
        goto clear_return;
    }

    memcpy(&(tmp_key_request.cpu_svn), &(report.body.cpu_svn), sizeof(sgx_cpu_svn_t));
    memcpy(&(tmp_key_request.isv_svn), &(report.body.isv_svn), sizeof(sgx_isv_svn_t));
    tmp_key_request.key_name = SGX_KEYSELECT_SEAL;
    tmp_key_request.key_policy = key_policy;
    tmp_key_request.attribute_mask.flags = attribute_mask.flags;
    tmp_key_request.attribute_mask.xfrm = attribute_mask.xfrm;
    memcpy(&(tmp_key_request.key_id), &keyID, sizeof(sgx_key_id_t));
    tmp_key_request.misc_mask = misc_mask;

    err = sgx_seal_data_iv(additional_MACtext_length, p_additional_MACtext,
        0, NULL, payload_iv, &tmp_key_request, p_sealed_data);

    if (err == SGX_SUCCESS)
    {
        // Copy data from the temporary key request buffer to the sealed data blob
        memcpy(&(p_sealed_data->key_request), &tmp_key_request, sizeof(sgx_key_request_t));
    }

clear_return:
    // Clear temp state
    memset_s(&report, sizeof(sgx_report_t), 0, sizeof(sgx_report_t));
    memset_s(&keyID, sizeof(sgx_key_id_t), 0, sizeof(sgx_key_id_t));
    return err;
}
Example #4
0
extern "C" sgx_status_t sgx_unmac_aadata(const sgx_sealed_data_t *p_sealed_data,
                                        uint8_t *p_additional_MACtext,
                                        uint32_t *p_additional_MACtext_length)
{
    sgx_status_t err = SGX_ERROR_UNEXPECTED;
    // Ensure the the sgx_sealed_data_t members are all inside enclave before using them.
    if ((p_sealed_data == NULL) || (!sgx_is_within_enclave(p_sealed_data, sizeof(sgx_sealed_data_t))))
    {
        return SGX_ERROR_INVALID_PARAMETER;
    }

    // If using this API, the sealed blob must have no encrypted data. 
    // So the encryt_text_length must be 0.
    uint32_t encrypt_text_length = sgx_get_encrypt_txt_len(p_sealed_data);
    if (encrypt_text_length != 0)
    {
        return SGX_ERROR_MAC_MISMATCH; // Return error indicating the blob is corrupted
    }

    // The sealed blob must have AAD. So the add_text_length must not be 0.
    uint32_t add_text_length = sgx_get_add_mac_txt_len(p_sealed_data);
    if (add_text_length == UINT32_MAX || add_text_length == 0)
    {
        return SGX_ERROR_MAC_MISMATCH; // Return error indicating the blob is corrupted
    }
    uint32_t sealedDataSize = sgx_calc_sealed_data_size(add_text_length, encrypt_text_length);
    if (sealedDataSize == UINT32_MAX)
    {
        return SGX_ERROR_MAC_MISMATCH; // Return error indicating the blob is corrupted
    }

    //
    // Check parameters
    //
    // Ensure sealed data blob is within an enclave during the sealing process
    if (!sgx_is_within_enclave(p_sealed_data, sealedDataSize))
    {
        return SGX_ERROR_INVALID_PARAMETER;
    }
    if (p_additional_MACtext == NULL || p_additional_MACtext_length == NULL)
    {
        return SGX_ERROR_INVALID_PARAMETER;
    }

    // Ensure AAD does not cross enclave boundary
    if (!(sgx_is_within_enclave(p_additional_MACtext, add_text_length) || 
        sgx_is_outside_enclave(p_additional_MACtext, add_text_length)))
    {
        return SGX_ERROR_INVALID_PARAMETER;
    }

    uint32_t additional_MACtext_length = *p_additional_MACtext_length;
    if (additional_MACtext_length < add_text_length) {
        return SGX_ERROR_INVALID_PARAMETER;
    }

    err = sgx_unseal_data_helper(p_sealed_data, p_additional_MACtext, add_text_length,
        NULL, encrypt_text_length);
    if (err == SGX_SUCCESS)
    {
        *p_additional_MACtext_length = add_text_length;
    }
    return err;
}
Example #5
0
/*
 * @func encrypt_ip modifies the content of some sections. 
 * @param INOUT uint8_t* elf_buf, buffer of ELF binary
 * @param size_t elf_size, size of ELF binary in bytes
 * @param IN uint8_t* key, AES-GCM-128 key
 * @param bool debug, true iff enclave is requried to support debug
 * @return encip_ret_e:
 * ENCIP_ERROR_ENCRYPTIP_INVALID_PARAM if any input parameter is NULL
 * Respective error results in case any of the following functions fail: 
 * parse_elf, get_pcl_tbl init_random_iv, encrypt_or_clear_ip_sections or sha256
 * ENCIP_ERROR_MEM_ALLOC if memory allocation fails
 * ENCIP_ERROR_SEALED_BUF_SIZE if sealed buf size exceeds the size allocated for it in PCL table
 * ENCIP_SUCCESS if success
 */
encip_ret_e encrypt_ip(INOUT uint8_t* elf_buf, size_t elf_size, IN uint8_t* key, bool debug)
{
    if(NULL == elf_buf || NULL == key)
        return ENCIP_ERROR_ENCRYPTIP_INVALID_PARAM;
    encip_ret_e ret = ENCIP_ERROR_FAIL;
    pcl_data_t dat = {
        .elf_sec = 0,
        .shstrndx = 0,
        .sections_names = NULL,
        .phdr = NULL,
        .nsections = 0, 
        .nsegments = 0,
    };
    pcl_table_t* tbl = NULL;

    ret = parse_elf(elf_buf, elf_size, &dat);
    if(ENCIP_ERROR(ret))
        return ret;

    ret = get_pcl_tbl(elf_buf, elf_size, &dat, &tbl);
    if(ENCIP_ERROR(ret))
        return ret;

    // Verify state of binary:
    if(PCL_CIPHER == tbl->pcl_state) 
        return ENCIP_ERROR_ALREADY_ENCRYPTED;
    if(PCL_PLAIN  != tbl->pcl_state)
        return ENCIP_ERROR_IMPROPER_STATE;

    // Encrypt or clear IP sections: 
    uint32_t num_rvas = 0;
    ret = encrypt_or_clear_ip_sections(&dat, key, elf_buf, elf_size, tbl, &num_rvas, debug);
    if(ENCIP_ERROR(ret))
        return ret;

    // Set GUID:
    memcpy(tbl->pcl_guid, g_pcl_guid, sizeof(tbl->pcl_guid));

    // Set sealed blob size:
    tbl->sealed_blob_size = (size_t)sgx_calc_sealed_data_size(SGX_PCL_GUID_SIZE, SGX_AESGCM_KEY_SIZE);
    // Verify calculated size equals hard coded size of buffer in PCL table:
    if(PCL_SEALED_BLOB_SIZE != tbl->sealed_blob_size)
        return ENCIP_ERROR_SEALED_BUF_SIZE;

    // Set num RVAs:
    tbl->num_rvas = num_rvas;

    // Set decryption key sha256 hash result:
    ret = sha256(key, SGX_AESGCM_KEY_SIZE, tbl->decryption_key_hash);
    if(ENCIP_ERROR(ret))
        return ret;

    // Set PCL state
    tbl->pcl_state = PCL_CIPHER;

    return ENCIP_SUCCESS;
}

/*
 * @func print_usage prints sgx_encrypt usage instructions 
 * @param IN char* encip_name is the name of the application
 */
void print_usage(IN char* encip_name)
{
    printf("\n");
    printf("\tUsage: \n");
    printf("\t  %s -i <input enclave so file name> -o <output enclave so file name> -k <key file name> [-d]\n",
            encip_name);
    printf("\t  -d (optional) prevents the tool from disabling the debug capabilities\n");
    printf("\n");
}
Example #6
0
uint32_t ecall_get_required_size(uint32_t add_mac_txt_size, uint32_t txt_encrypt_size){
    return sgx_calc_sealed_data_size(add_mac_txt_size, txt_encrypt_size);
}