mirror of
https://github.com/intel/linux-sgx
synced 2026-06-08 14:49:32 +00:00
1bf092a389
Supported the Key Separation and Sharing (KSS) feature in Simulation mode. Upgraded to OpenSSL 1.1.1t. Upgraded Intel(R) SGX Quote Verification Enclave to integrate SgxSSL/OpenSSL version 1.1.1t. Added new API in quote verification library to extract FMSPC (Family-Model-SteppingPlatform-CustomSKU) value from ECDSA quote. Added Rust support for SGX ECDSA quote generation. Added Linux kernel 5.19 support in TDX R3AAL (Ring 3 Attestation Abstraction Layer). Removed Protobuf in TDX QGS (Quote Generation Service) and R3AAL (Ring 3 Attestation Abstraction Layer). Fixed bugs. Signed-off-by: Li, Xun <xun.li@intel.com>
237 lines
7.4 KiB
C++
237 lines
7.4 KiB
C++
/*
|
|
* Copyright (C) 2011-2021 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 <openssl/aes.h>
|
|
#include <openssl/sha.h>
|
|
#include <openssl/modes.h>
|
|
#include <sgx_tseal.h>
|
|
#include <sgx_tcrypto.h>
|
|
#include <pcl_common.h>
|
|
#include <pcl_internal.h>
|
|
#include <pcl_crypto_internal.h>
|
|
|
|
/*
|
|
* @func pcl_gcm_decrypt applies AES-GCM-128
|
|
* @param OUT uint8_t* plaintext, input plain text buffer
|
|
* @param IN uint8_t* ciphertext, output cipher text buffer
|
|
* @param size_t textlen, size of buffer in bytes
|
|
* @param IN uint8_t* aad, aditional authenticated data
|
|
* @param size_t aad_len, size of aditional authenticated data
|
|
* @param IN uint8_t* key, 16 bytes decryption key
|
|
* @param IN uint8_t* iv, 12 bytes IV
|
|
* @param IN uint8_t* tag, 16 bytes TAG result
|
|
* @return sgx_status_t
|
|
* SGX_ERROR_INVALID_PARAMETER if any pointer is NULL except for aad
|
|
* SGX_ERROR_UNEXPECTED if any of the following functions fail:
|
|
* pcl_vpaes_set_encrypt_key, pcl_CRYPTO_gcm128_aad or pcl_CRYPTO_gcm128_decrypt
|
|
* SGX_ERROR_PCL_MAC_MISMATCH if MAC mismatch when calling pcl_CRYPTO_gcm128_finish
|
|
* SGX_SUCCESS if successfull
|
|
*/
|
|
sgx_status_t pcl_gcm_decrypt(
|
|
OUT uint8_t* plaintext,
|
|
IN uint8_t* ciphertext,
|
|
size_t textlen,
|
|
IN uint8_t* aad,
|
|
size_t aad_len,
|
|
IN uint8_t* key,
|
|
IN uint8_t* iv,
|
|
IN uint8_t* tag)
|
|
{
|
|
sgx_status_t ret_status = SGX_ERROR_INVALID_PARAMETER;
|
|
|
|
if( NULL == plaintext ||
|
|
NULL == ciphertext ||
|
|
NULL == key ||
|
|
NULL == iv ||
|
|
NULL == tag)
|
|
{
|
|
return SGX_ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
AES_KEY wide_key = {.rd_key={},.rounds=0};
|
|
GCM128_CONTEXT gcm_ctx;
|
|
|
|
int ret = pcl_vpaes_set_encrypt_key(key, PCL_AES_BLOCK_LEN_BITS, &wide_key);
|
|
if(0 != ret)
|
|
{
|
|
ret_status = SGX_ERROR_UNEXPECTED;
|
|
goto Label_zero_wide_key;
|
|
}
|
|
|
|
pcl_CRYPTO_gcm128_init(&gcm_ctx, &wide_key, (block128_f)pcl_vpaes_encrypt);
|
|
|
|
pcl_CRYPTO_gcm128_setiv(&gcm_ctx, iv, SGX_AESGCM_IV_SIZE);
|
|
|
|
if(NULL != aad)
|
|
{
|
|
ret = pcl_CRYPTO_gcm128_aad(&gcm_ctx, aad, aad_len);
|
|
if(0 != ret)
|
|
{
|
|
ret_status = SGX_ERROR_UNEXPECTED;
|
|
goto Label_zero_buffers;
|
|
}
|
|
}
|
|
|
|
ret = pcl_CRYPTO_gcm128_decrypt(
|
|
&gcm_ctx,
|
|
ciphertext,
|
|
plaintext,
|
|
textlen);
|
|
if(0 != ret)
|
|
{
|
|
ret_status = SGX_ERROR_UNEXPECTED;
|
|
goto Label_zero_buffers;
|
|
}
|
|
|
|
ret = pcl_CRYPTO_gcm128_finish(&gcm_ctx, tag, SGX_CMAC_MAC_SIZE);
|
|
if(0 != ret)
|
|
{
|
|
ret_status = SGX_ERROR_PCL_MAC_MISMATCH;
|
|
goto Label_zero_buffers;
|
|
}
|
|
|
|
ret_status = SGX_SUCCESS;
|
|
|
|
// Scrab secrets from stack:
|
|
Label_zero_buffers:
|
|
pcl_volatile_memset((volatile void*)(&gcm_ctx), 0, sizeof(gcm_ctx));
|
|
Label_zero_wide_key:
|
|
pcl_volatile_memset((volatile void*)(&wide_key), 0, sizeof(wide_key));
|
|
|
|
return ret_status;
|
|
}
|
|
|
|
/*
|
|
* @func pcl_sha256 calculates the payload SHA256
|
|
* @param IN uint8_t* buf, payload buffer
|
|
* @param size_t buflen, buffer size in bytes
|
|
* @param OUT uint8_t* hash, SHA256 result
|
|
*/
|
|
sgx_status_t pcl_sha256(IN uint8_t* buf, size_t buflen, OUT uint8_t* hash)
|
|
{
|
|
if(NULL == buf || NULL == hash)
|
|
{
|
|
return SGX_ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
SHA256_CTX sha256;
|
|
|
|
pcl_SHA256_Init(&sha256);
|
|
|
|
pcl_SHA256_Update(&sha256, buf, buflen);
|
|
|
|
pcl_SHA256_Final(hash, &sha256);
|
|
|
|
pcl_volatile_memset((volatile void*)(&sha256), 0, sizeof(SHA256_CTX));
|
|
|
|
return SGX_SUCCESS;
|
|
}
|
|
|
|
#ifdef SE_SIM
|
|
|
|
/*
|
|
* @func pcl_cmac calcualtes CMAC-128 on payload
|
|
* @param IN const sgx_cmac_128bit_key_t *p_key, CMAC key
|
|
* @param IN const uint8_t *p_src, input buffer
|
|
* @param uint32_t src_len, buffer size in bytes
|
|
* @param OUT sgx_cmac_128bit_tag_t *p_mac, 16 bytes resulting MAC
|
|
* @return int, -1 if p_key, p_src or p_mac are NULL, 0 if success
|
|
*/
|
|
int pcl_cmac(
|
|
const sgx_cmac_128bit_key_t *p_key,
|
|
const uint8_t *p_src,
|
|
uint32_t src_len,
|
|
sgx_cmac_128bit_tag_t *p_mac)
|
|
{
|
|
if(NULL == p_key || NULL == p_src || NULL == p_mac)
|
|
{
|
|
return -1;
|
|
}
|
|
unsigned char iv[PCL_COUNTER_SIZE] = { 0 };
|
|
unsigned char aux[PCL_AES_BLOCK_LEN] = { 0 };
|
|
unsigned char k1[PCL_AES_BLOCK_LEN] = { 0 };
|
|
unsigned char k2[PCL_AES_BLOCK_LEN] = { 0 };
|
|
|
|
AES_KEY wide_key = {.rd_key={},.rounds=0};
|
|
pcl_vpaes_set_encrypt_key((const unsigned char *)p_key, PCL_AES_BLOCK_LEN_BITS, &wide_key);
|
|
|
|
// Apply AES-CBC encrypt on input = 0^16 and IV = 0^16:
|
|
pcl_vpaes_cbc_encrypt(iv, aux, PCL_AES_BLOCK_LEN, &wide_key, iv, 1);
|
|
|
|
// Use result to generate K1:
|
|
make_kn(k1, aux, PCL_AES_BLOCK_LEN);
|
|
|
|
// Generate k2:
|
|
make_kn(k2, k1, PCL_AES_BLOCK_LEN);
|
|
|
|
// Digest message except for last block:
|
|
pcl_memset(iv, 0, PCL_COUNTER_SIZE);
|
|
while(src_len > PCL_AES_BLOCK_LEN)
|
|
{
|
|
pcl_vpaes_cbc_encrypt((uint8_t *)p_src, aux, PCL_AES_BLOCK_LEN, &wide_key, iv, 1);
|
|
src_len -= PCL_AES_BLOCK_LEN;
|
|
p_src += PCL_AES_BLOCK_LEN;
|
|
}
|
|
|
|
if (src_len == PCL_AES_BLOCK_LEN)
|
|
{
|
|
// last block is complete
|
|
// XOR K1 with last block of message:
|
|
for (int i = 0; i < PCL_AES_BLOCK_LEN; i++)
|
|
aux[i] = p_src[i] ^ k1[i];
|
|
}
|
|
else
|
|
{
|
|
// last block is not complete
|
|
// copy last block
|
|
uint8_t temp[PCL_AES_BLOCK_LEN] = {0};
|
|
if (src_len > 0)
|
|
{
|
|
for (int i = 0; i < src_len; i++)
|
|
{
|
|
temp[i] = p_src[i];
|
|
}
|
|
}
|
|
temp[src_len] = 0x80;
|
|
for (int i = 0; i < PCL_AES_BLOCK_LEN; i++)
|
|
{
|
|
aux[i] = temp[i] ^ k2[i];
|
|
}
|
|
}
|
|
|
|
// Apply AES-CBC encrypt on result and IV
|
|
pcl_vpaes_cbc_encrypt(aux, (uint8_t*)p_mac, PCL_AES_BLOCK_LEN, &wide_key, iv, 1);
|
|
return 0;
|
|
}
|
|
|
|
#endif // #ifdef SE_SIM
|
|
|