Skip to content
This repository has been archived by the owner on May 9, 2022. It is now read-only.

Commit

Permalink
feat(auth_enclave): return actual token size to avoid null trailer is…
Browse files Browse the repository at this point in the history
…sues

Co-authored-by: Pi Delport <pi@registree.io>
  • Loading branch information
longtomjr and PiDelport committed Jun 25, 2021
1 parent ea6f6e9 commit bd03587
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 39 deletions.
35 changes: 30 additions & 5 deletions codegen/auth_enclave/rtc_auth_t.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ typedef struct ms_issue_execution_token_t {
size_t ms_payload_len;
const ExecReqMetadata* ms_metadata;
uint8_t* ms_out_token_ptr;
size_t ms_out_token_len;
size_t ms_out_token_capacity;
size_t* ms_out_token_used;
} ms_issue_execution_token_t;

typedef struct ms_t_global_init_ecall_t {
Expand Down Expand Up @@ -669,23 +670,27 @@ static sgx_status_t SGX_CDECL sgx_issue_execution_token(void* pms)
size_t _len_metadata = sizeof(ExecReqMetadata);
ExecReqMetadata* _in_metadata = NULL;
uint8_t* _tmp_out_token_ptr = ms->ms_out_token_ptr;
size_t _tmp_out_token_len = ms->ms_out_token_len;
size_t _len_out_token_ptr = _tmp_out_token_len * sizeof(uint8_t);
size_t _tmp_out_token_capacity = ms->ms_out_token_capacity;
size_t _len_out_token_ptr = _tmp_out_token_capacity * sizeof(uint8_t);
uint8_t* _in_out_token_ptr = NULL;
size_t* _tmp_out_token_used = ms->ms_out_token_used;
size_t _len_out_token_used = sizeof(size_t);
size_t* _in_out_token_used = NULL;

if (sizeof(*_tmp_payload_ptr) != 0 &&
(size_t)_tmp_payload_len > (SIZE_MAX / sizeof(*_tmp_payload_ptr))) {
return SGX_ERROR_INVALID_PARAMETER;
}

if (sizeof(*_tmp_out_token_ptr) != 0 &&
(size_t)_tmp_out_token_len > (SIZE_MAX / sizeof(*_tmp_out_token_ptr))) {
(size_t)_tmp_out_token_capacity > (SIZE_MAX / sizeof(*_tmp_out_token_ptr))) {
return SGX_ERROR_INVALID_PARAMETER;
}

CHECK_UNIQUE_POINTER(_tmp_payload_ptr, _len_payload_ptr);
CHECK_UNIQUE_POINTER(_tmp_metadata, _len_metadata);
CHECK_UNIQUE_POINTER(_tmp_out_token_ptr, _len_out_token_ptr);
CHECK_UNIQUE_POINTER(_tmp_out_token_used, _len_out_token_used);

//
// fence after pointer checks
Expand Down Expand Up @@ -736,19 +741,39 @@ static sgx_status_t SGX_CDECL sgx_issue_execution_token(void* pms)

memset((void*)_in_out_token_ptr, 0, _len_out_token_ptr);
}
if (_tmp_out_token_used != NULL && _len_out_token_used != 0) {
if ( _len_out_token_used % sizeof(*_tmp_out_token_used) != 0)
{
status = SGX_ERROR_INVALID_PARAMETER;
goto err;
}
if ((_in_out_token_used = (size_t*)malloc(_len_out_token_used)) == NULL) {
status = SGX_ERROR_OUT_OF_MEMORY;
goto err;
}

ms->ms_retval = issue_execution_token((const uint8_t*)_in_payload_ptr, _tmp_payload_len, (const ExecReqMetadata*)_in_metadata, _in_out_token_ptr, _tmp_out_token_len);
memset((void*)_in_out_token_used, 0, _len_out_token_used);
}

ms->ms_retval = issue_execution_token((const uint8_t*)_in_payload_ptr, _tmp_payload_len, (const ExecReqMetadata*)_in_metadata, _in_out_token_ptr, _tmp_out_token_capacity, _in_out_token_used);
if (_in_out_token_ptr) {
if (memcpy_s(_tmp_out_token_ptr, _len_out_token_ptr, _in_out_token_ptr, _len_out_token_ptr)) {
status = SGX_ERROR_UNEXPECTED;
goto err;
}
}
if (_in_out_token_used) {
if (memcpy_s(_tmp_out_token_used, _len_out_token_used, _in_out_token_used, _len_out_token_used)) {
status = SGX_ERROR_UNEXPECTED;
goto err;
}
}

err:
if (_in_payload_ptr) free(_in_payload_ptr);
if (_in_metadata) free(_in_metadata);
if (_in_out_token_ptr) free(_in_out_token_ptr);
if (_in_out_token_used) free(_in_out_token_used);
return status;
}

Expand Down
2 changes: 1 addition & 1 deletion codegen/auth_enclave/rtc_auth_t.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ extern "C" {
#endif

CreateReportResult enclave_create_report(const sgx_target_info_t* p_qe3_target, EnclaveHeldData enclave_data, sgx_report_t* p_report);
IssueTokenResult issue_execution_token(const uint8_t* payload_ptr, size_t payload_len, const ExecReqMetadata* metadata, uint8_t* out_token_ptr, size_t out_token_len);
IssueTokenResult issue_execution_token(const uint8_t* payload_ptr, size_t payload_len, const ExecReqMetadata* metadata, uint8_t* out_token_ptr, size_t out_token_capacity, size_t* out_token_used);
void t_global_init_ecall(uint64_t id, const uint8_t* path, size_t len);
void t_global_exit_ecall(void);
SessionRequestResult session_request(sgx_enclave_id_t src_enclave_id);
Expand Down
8 changes: 5 additions & 3 deletions codegen/auth_enclave/rtc_auth_u.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ typedef struct ms_issue_execution_token_t {
size_t ms_payload_len;
const ExecReqMetadata* ms_metadata;
uint8_t* ms_out_token_ptr;
size_t ms_out_token_len;
size_t ms_out_token_capacity;
size_t* ms_out_token_used;
} ms_issue_execution_token_t;

typedef struct ms_t_global_init_ecall_t {
Expand Down Expand Up @@ -1224,15 +1225,16 @@ sgx_status_t rtc_auth_enclave_create_report(sgx_enclave_id_t eid, CreateReportRe
return status;
}

sgx_status_t rtc_auth_issue_execution_token(sgx_enclave_id_t eid, IssueTokenResult* retval, const uint8_t* payload_ptr, size_t payload_len, const ExecReqMetadata* metadata, uint8_t* out_token_ptr, size_t out_token_len)
sgx_status_t rtc_auth_issue_execution_token(sgx_enclave_id_t eid, IssueTokenResult* retval, const uint8_t* payload_ptr, size_t payload_len, const ExecReqMetadata* metadata, uint8_t* out_token_ptr, size_t out_token_capacity, size_t* out_token_used)
{
sgx_status_t status;
ms_issue_execution_token_t ms;
ms.ms_payload_ptr = payload_ptr;
ms.ms_payload_len = payload_len;
ms.ms_metadata = metadata;
ms.ms_out_token_ptr = out_token_ptr;
ms.ms_out_token_len = out_token_len;
ms.ms_out_token_capacity = out_token_capacity;
ms.ms_out_token_used = out_token_used;
status = sgx_ecall(eid, 1, &ocall_table_rtc_auth, &ms);
if (status == SGX_SUCCESS && retval) *retval = ms.ms_retval;
return status;
Expand Down
2 changes: 1 addition & 1 deletion codegen/auth_enclave/rtc_auth_u.h
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ int32_t SGX_UBRIDGE(SGX_NOCONVENTION, u_sgxprotectedfs_do_file_recovery, (const
#endif

sgx_status_t rtc_auth_enclave_create_report(sgx_enclave_id_t eid, CreateReportResult* retval, const sgx_target_info_t* p_qe3_target, EnclaveHeldData enclave_data, sgx_report_t* p_report);
sgx_status_t rtc_auth_issue_execution_token(sgx_enclave_id_t eid, IssueTokenResult* retval, const uint8_t* payload_ptr, size_t payload_len, const ExecReqMetadata* metadata, uint8_t* out_token_ptr, size_t out_token_len);
sgx_status_t rtc_auth_issue_execution_token(sgx_enclave_id_t eid, IssueTokenResult* retval, const uint8_t* payload_ptr, size_t payload_len, const ExecReqMetadata* metadata, uint8_t* out_token_ptr, size_t out_token_capacity, size_t* out_token_used);
sgx_status_t rtc_auth_t_global_init_ecall(sgx_enclave_id_t eid, uint64_t id, const uint8_t* path, size_t len);
sgx_status_t rtc_auth_t_global_exit_ecall(sgx_enclave_id_t eid);
sgx_status_t rtc_auth_session_request(sgx_enclave_id_t eid, SessionRequestResult* retval, sgx_enclave_id_t src_enclave_id);
Expand Down
5 changes: 3 additions & 2 deletions rtc_auth_enclave/rtc_auth.edl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ enclave {
public IssueTokenResult issue_execution_token([in, count=payload_len]const uint8_t* payload_ptr,
size_t payload_len,
[in]const ExecReqMetadata* metadata,
[out, count=out_token_len]uint8_t* out_token_ptr,
size_t out_token_len);
[out, count=out_token_capacity]uint8_t* out_token_ptr,
size_t out_token_capacity,
[out] size_t* out_token_used);
};
};
38 changes: 15 additions & 23 deletions rtc_auth_enclave/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@ use uuid::Uuid;

/// Minimum size for the out_token parameter's buffer.
///
/// From my testing, the token size were never bigger than 400.
/// So this value refers to: 400 (for the token) + 16 (Authentication bytes from NaCl)
const MIN_OUT_TOKEN_LEN: usize = 416;
/// From my testing, the total token size (including auth bytes) were never bigger than 500.
const MIN_OUT_TOKEN_LEN: usize = 500;

/// Maximum size for the out_token parameter's buffer.
const MAX_OUT_TOKEN_LEN: usize = 1000;
Expand All @@ -53,33 +52,35 @@ pub unsafe extern "C" fn issue_execution_token(
payload_len: usize,
metadata_ptr: *const ExecReqMetadata,
out_token_ptr: *mut u8,
out_token_len: usize,
out_token_capacity: usize,
out_token_used: *mut usize,
) -> IssueTokenResult {
// Ensure that the out token len is reasonable before proceeding
if out_token_capacity < MIN_OUT_TOKEN_LEN || out_token_capacity > MAX_OUT_TOKEN_LEN {
return EcallResult::Err(ExecTokenError::OutputBufferSize);
}

let payload = unsafe { slice::from_raw_parts(payload_ptr, payload_len) };
let metadata = unsafe { &*metadata_ptr };

match issue_execution_token_impl(payload, metadata, out_token_len) {
Ok(message) => {
assert_eq!(message.ciphertext.len(), out_token_len);
match issue_execution_token_impl(payload, metadata) {
Ok(message) if message.ciphertext.len() <= out_token_capacity => {
let out_token_len = message.ciphertext.len();
unsafe {
*out_token_used = out_token_len;
ptr::copy_nonoverlapping(message.ciphertext.as_ptr(), out_token_ptr, out_token_len);
}
EcallResult::Ok(message.nonce)
}
Ok(_) => EcallResult::Err(ExecTokenError::OutputBufferSize),
Err(err) => EcallResult::Err(err),
}
}

fn issue_execution_token_impl(
payload: &[u8],
metadata: &ExecReqMetadata,
max_ciphertext_len: usize,
) -> Result<EncryptedMessage, ExecTokenError> {
// Ensure that the out token len is reasonable before proceeding
if max_ciphertext_len < MIN_OUT_TOKEN_LEN || max_ciphertext_len > MAX_OUT_TOKEN_LEN {
return Err(ExecTokenError::OutputBufferSize);
}

let mut crypto = Crypto::new();
let message_bytes =
crypto.decrypt_message(payload, &metadata.uploader_pub_key, &metadata.nonce)?;
Expand All @@ -97,16 +98,7 @@ fn issue_execution_token_impl(
dataset_size,
)?;

let mut token_vec = token.into_bytes();

// TODO: Move this check before persistence
if max_ciphertext_len < token_vec.len() - 16 {
return Err(ExecTokenError::OutputBufferSize);
}

// Grow the plaintext vector to the max ciphertext size - 16
// The 16 refers to the authentication bytes that gets added by NaCl
token_vec.resize(max_ciphertext_len - 16, 0);
let token_vec = token.into_bytes();

Ok(crypto.encrypt_message(
Secret::new(token_vec.into_boxed_slice()),
Expand Down
11 changes: 7 additions & 4 deletions rtc_uenclave/src/enclaves/rtc_auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ pub mod ecalls {
metadata: ExecReqMetadata,
) -> Result<EncryptedMessage, EcallError<ExecTokenError>> {
// See MAX / MIN_OUT_TOKEN_LEN in rtc_auth_enclave
let mut out_token_buffer = vec![0u8; 416].into_boxed_slice();
let mut out_token_buffer = vec![0u8; 500];
let mut out_token_used = 0;
let mut retval = IssueTokenResult::Ok([0u8; 24]);

// Safety: Since the payload, and out buffer is allocated and valid this will be
Expand All @@ -84,14 +85,16 @@ pub mod ecalls {
&metadata,
out_token_buffer.as_mut_ptr(),
out_token_buffer.len(),
&mut out_token_used,
)
};

let x: Result<Nonce, EcallError<ExecTokenError>> = retval.to_ecall_err(res).into();

x.map(|r| EncryptedMessage {
ciphertext: out_token_buffer,
nonce: r,
x.map(|nonce| {
out_token_buffer.truncate(out_token_used);
let ciphertext = out_token_buffer.into_boxed_slice();
EncryptedMessage { ciphertext, nonce }
})
}
}

0 comments on commit bd03587

Please sign in to comment.