-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add `mc-sgx-io` which provides functionality for io streams from an SGX enclave
- Loading branch information
1 parent
b6c5142
commit d75d963
Showing
6 changed files
with
160 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
[workspace] | ||
members = [ | ||
"alloc", | ||
"io", | ||
"io/untrusted", | ||
] | ||
exclude = [ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
[package] | ||
name = "mc-sgx-io" | ||
version = "0.1.0" | ||
edition = "2021" | ||
authors = ["MobileCoin"] | ||
rust-version = "1.62.1" | ||
license = "Apache-2.0" | ||
readme = "README.md" | ||
repository = "https://github.com/mobilecoinfoundation/sgx-std" | ||
description = "IO implementation for use inside of SGX enclaves" | ||
categories = ["hardware-support", "no-std"] | ||
keywords = ["sgx", "no-std"] | ||
|
||
[dependencies] | ||
mc-sgx-core-sys-types = "0.4.0" | ||
mc-sgx-core-types = "0.4.0" | ||
mc-sgx-util = "0.4.0" | ||
|
||
[dev-dependencies] | ||
once_cell = "1.16.0" | ||
serial_test = "0.9.0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# MobileCoin SGX: IO in Enclave | ||
|
||
[![Project Chat][chat-image]][chat-link]<!-- | ||
-->![License][license-image]<!-- | ||
-->![Target][target-image]<!-- | ||
-->[![Crates.io][crate-image]][crate-link]<!-- | ||
-->[![Docs Status][docs-image]][docs-link]<!-- | ||
-->[![Dependency Status][deps-image]][deps-link] | ||
|
||
Provide IO streams for use in an SGX enclave | ||
|
||
[chat-image]: https://img.shields.io/discord/844353360348971068?style=flat-square | ||
[chat-link]: https://mobilecoin.chat | ||
[license-image]: https://img.shields.io/crates/l/mc-sgx-io?style=flat-square | ||
[target-image]: https://img.shields.io/badge/target-sgx-red?style=flat-square | ||
[crate-image]: https://img.shields.io/crates/v/mc-sgx-io.svg?style=flat-square | ||
[crate-link]: https://crates.io/crates/mc-sgx-io | ||
[docs-image]: https://img.shields.io/docsrs/mc-sgx-io?style=flat-square | ||
[docs-link]: https://docs.rs/crate/mc-sgx-io | ||
[deps-image]: https://deps.rs/crate/mc-sgx-io/0.1.0/status.svg?style=flat-square | ||
[deps-link]: https://deps.rs/crate/mc-sgx-io/0.1.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
// Copyright (c) 2022 The MobileCoin Foundation | ||
|
||
#![doc = include_str!("../README.md")] | ||
#![deny(missing_docs, missing_debug_implementations)] | ||
#![no_std] | ||
|
||
use core::ffi::c_void; | ||
use mc_sgx_core_sys_types::sgx_status_t; | ||
use mc_sgx_core_types::Error; | ||
use mc_sgx_util::ResultInto; | ||
|
||
/// Attempts to write the entire buffer into the hosts stderr sink. | ||
/// | ||
/// # Arguments | ||
/// * `buffer` - The buffer to write. | ||
/// | ||
/// # Errors | ||
/// If there is any error writing all of `buffer` to the sink. No | ||
/// assumptions should be made about the amount that was written to the sink | ||
/// when an error occurs. | ||
pub fn stderr_write_all(buffer: &[u8]) -> Result<(), Error> { | ||
unsafe { ocall_stderr(buffer.as_ptr() as *const c_void, buffer.len()) }.into_result() | ||
} | ||
|
||
extern "C" { | ||
/// The ocall to send stderr messages to | ||
/// | ||
/// # Arguments | ||
/// * `input` - The input buffer/stream. Should be ui8/bytes | ||
/// * `len` - The byte length of `input` | ||
/// | ||
/// # Returns | ||
/// `sgx_status_t::SGX_SUCCESS` when all of input was successfully written | ||
/// to the untrusted stderr sink. | ||
/// An error status if not all of the data could be written to the sink. No | ||
/// assumptions are made about how much data was written on error. | ||
fn ocall_stderr(input: *const c_void, len: usize) -> sgx_status_t; | ||
} | ||
|
||
// Done out here so that `serial_test` works, since it uses "::std" in the macro | ||
#[cfg(test)] | ||
extern crate std; | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
use core::slice; | ||
use once_cell::sync::Lazy; | ||
use serial_test::serial; | ||
use std::string::String; | ||
use std::sync::Mutex; | ||
|
||
static TEST_STREAM: Lazy<Mutex<String>> = Lazy::new(|| Mutex::new(String::new())); | ||
static TEST_STREAM_RESULT: Lazy<Mutex<sgx_status_t>> = | ||
Lazy::new(|| Mutex::new(sgx_status_t::SGX_SUCCESS)); | ||
|
||
fn reset_test_stream() { | ||
let mut stream = TEST_STREAM.lock().expect("Mutex has been poisoned"); | ||
stream.clear(); | ||
let mut status = TEST_STREAM_RESULT.lock().expect("Mutex has been poisoned"); | ||
*status = sgx_status_t::SGX_SUCCESS; | ||
} | ||
|
||
#[no_mangle] | ||
extern "C" fn ocall_stderr(input: *const c_void, len: usize) -> sgx_status_t { | ||
let bytes = unsafe { slice::from_raw_parts(input as *const u8, len) }; | ||
let message = | ||
std::str::from_utf8(bytes).expect("Expected valid UTF8 from stderr in enclave"); | ||
let mut stream = TEST_STREAM.lock().expect("Mutex has been poisoned"); | ||
stream.clear(); | ||
stream.push_str(message); | ||
let status = TEST_STREAM_RESULT.lock().expect("Mutex has been poisoned"); | ||
*status | ||
} | ||
|
||
#[test] | ||
#[serial] | ||
fn single_line_output_to_stderr() { | ||
reset_test_stream(); | ||
stderr_write_all(b"what").expect("Expected the write to succeed"); | ||
|
||
let written = TEST_STREAM.lock().expect("Mutex has been poisoned"); | ||
assert_eq!(written.as_str(), "what"); | ||
} | ||
|
||
#[test] | ||
#[serial] | ||
fn multi_line_output_to_stderr() { | ||
reset_test_stream(); | ||
stderr_write_all(b"this\nhas\nmultiple\nlines").expect("Expected the write to succeed"); | ||
|
||
let written = TEST_STREAM.lock().expect("Mutex has been poisoned"); | ||
assert_eq!(written.as_str(), "this\nhas\nmultiple\nlines"); | ||
} | ||
|
||
#[test] | ||
#[serial] | ||
fn error_when_outputting_to_stderr() { | ||
reset_test_stream(); | ||
let expected_error = sgx_status_t::SGX_ERROR_FILE_BAD_STATUS; | ||
{ | ||
let mut status = TEST_STREAM_RESULT.lock().expect("Mutex has been poisoned"); | ||
*status = expected_error; | ||
} | ||
|
||
let error = stderr_write_all(b"what").unwrap_err(); | ||
assert_eq!(error, Error::FileBadStatus); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters