Skip to content

Commit

Permalink
fuzz/*: fuzz rats-tls APIs in SGX mode
Browse files Browse the repository at this point in the history
use libfuzzer to fuzz rats-tls API `rats_tls_init()`, `rats_tls_negotiate()`, `rats_tls_transmit()`, `rats_tls_receive()`, `rats_tls_cleanup()` in sgx mode.

Signed-off-by: Pengyu Chen <[email protected]>
  • Loading branch information
Ben-cpy committed Oct 31, 2023
1 parent 190181b commit d427a4e
Show file tree
Hide file tree
Showing 19 changed files with 775 additions and 30 deletions.
10 changes: 10 additions & 0 deletions cmake/CompilerOptions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2")
endif()

if((BUILD_FUZZ) AND (SGX))
string(REPLACE "-std=gnu11" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
endif()

# SGX mode
if(SGX)
if(SGX_HW)
Expand Down Expand Up @@ -58,6 +62,11 @@ if(SGX)

set(SGX_COMMON_CFLAGS "${SGX_COMMON_FLAGS} -Wstrict-prototypes -Wunsuffixed-float-constants -Wno-implicit-function-declaration -std=c11")
set(SGX_COMMON_CXXFLAGS "${SGX_COMMON_FLAGS} -Wnon-virtual-dtor -std=c++11")
if((BUILD_FUZZ) AND (SGX))
string(REPLACE "-std=c11" "" SGX_COMMON_CFLAGS "${SGX_COMMON_CFLAGS}")
string(REPLACE "-Wunsuffixed-float-constants" "" SGX_COMMON_CFLAGS "${SGX_COMMON_CFLAGS}")
string(REPLACE "-std=c++11" "" SGX_COMMON_CXXFLAGS "${SGX_COMMON_CXXFLAGS}")
endif()

set(ENCLAVE_INCLUDES "${SGX_INCLUDE}" "${SGX_TLIBC_INCLUDE}" "${SGX_LIBCXX_INCLUDE}" "/usr/include")
set(ENCLAVE_C_FLAGS "${CMAKE_C_FLAGS} ${SGX_COMMON_CFLAGS} ${ENCLAVE_COMMON_FLAGS}")
Expand All @@ -67,3 +76,4 @@ if(SGX)
set(APP_C_FLAGS "${CMAKE_C_FLAGS} ${SGX_COMMON_CFLAGS} ${APP_COMMON_FLAGS}")
set(APP_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SGX_COMMON_CXXFLAGS} ${APP_COMMON_FLAGS}")
endif()

11 changes: 8 additions & 3 deletions fuzz/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
add_subdirectory(tls_init)
add_subdirectory(tls_negotiate)
if(SGX)
add_subdirectory(tls_sgx_mode)
add_subdirectory(sgx-stub-enclave)
else()
add_subdirectory(tls_init)
add_subdirectory(tls_negotiate)
add_subdirectory(tls_transmit)
endif()
add_subdirectory(tls_server)
add_subdirectory(tls_transmit)
27 changes: 27 additions & 0 deletions fuzz/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,20 @@ cmake -DRATS_TLS_BUILD_MODE="host" -DBUILD_SAMPLES=on -DBUILD_FUZZ=on -H. -Bbuil
make -C build install
```

For SGX mode, please run the following command.

```shell
cmake -DRATS_TLS_BUILD_MODE="sgx" -DBUILD_SAMPLES=off -DBUILD_FUZZ=on -H. -Bbuild
make -C build install
```

Attention! If you run fuzz host program before, you should clean the environment and vice versa.

```bash
make -C build clean # clean the environment
make -C build uninstall
```

# FUZZ

## rats_tls_init API
Expand Down Expand Up @@ -65,4 +79,17 @@ base64 /dev/urandom | head -c 1500000 > c1
cd ..
./fuzz_server &
./fuzz_transmit -max_len=1500000 -len_control=0 corpus # len_control=0 means try genarating input with size up to max_len
```

# FUZZ in SGX mode

We integrate the fuzz program for these apis into one program `fuzz_sgx_mode`, start the `fuzz_server` first, and then run `fuzz_sgx_mode` to start fuzz.

```shell
cd /usr/share/rats_tls/fuzz/
mkdir corpus && cd corpus # create corpus dir and fill in random string
base64 /dev/urandom | head -c 1500000 > c1
cd ..
./fuzz_server &
./fuzz_sgx_mode -max_len=1500000 -len_control=0 corpus
```
83 changes: 83 additions & 0 deletions fuzz/sgx-stub-enclave/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Project name
project(sgx-stub-enclave CXX)

set(CMAKE_CXX_COMPILER "/usr/bin/clang++")
set(CMAKE_CXX_FLAGS "-g ${CMAKE_CXX_FLAGS}")
set(RATS_TLS_INSTALL_FUZZ_PATH /usr/share/rats-tls/fuzz)

if((BUILD_SAMPLES) OR (BUILD_FUZZ))
set(INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../../src/include
${CMAKE_CURRENT_SOURCE_DIR}/../../src/include/rats-tls
${CMAKE_CURRENT_SOURCE_DIR}/../../src/include/edl
${CMAKE_CURRENT_SOURCE_DIR}/../../src/external/sgx-ssl/intel-sgx-ssl/src/intel-sgx-ssl/Linux/package/include
)

set(LIBRARY_DIRS ${INTEL_SGXSSL_LIB_PATH}
${LIBCBOR_LIB_PATH}
${CMAKE_BINARY_DIR}/src
${CMAKE_BINARY_DIR}/src/crypto_wrappers/nullcrypto
${CMAKE_BINARY_DIR}/src/crypto_wrappers/openssl
${CMAKE_BINARY_DIR}/src/tls_wrappers/nulltls
${CMAKE_BINARY_DIR}/src/tls_wrappers/openssl
${CMAKE_BINARY_DIR}/src/verifiers/nullverifier
${CMAKE_BINARY_DIR}/src/verifiers/sgx-ecdsa-qve
${CMAKE_BINARY_DIR}/src/verifiers/tdx-ecdsa
${CMAKE_BINARY_DIR}/src/verifiers/sgx-la
${CMAKE_BINARY_DIR}/src/attesters/nullattester
${CMAKE_BINARY_DIR}/src/attesters/sgx-ecdsa
${CMAKE_BINARY_DIR}/src/attesters/sgx-la
)

set(EDL_SEARCH_PATHS ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/../../src/include/edl
)
else()
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(CustomInstallDirs)
include(FindRatsTls)
if(NOT RATS_TLS_FOUND)
message(FATAL_ERROR "Failed to find rats_tls!")
endif()
include(FindSGX)
if(NOT SGX_FOUND)
message(FATAL_ERROR "Failed to find sgx!")
endif()
include(CompilerOptions)
include(SGXCommon)

set(INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../../src/include
${CMAKE_CURRENT_SOURCE_DIR}/../../src/include/rats-tls
${CMAKE_CURRENT_SOURCE_DIR}/../../src/include/edl)

set(LIBRARY_DIRS ${RATS_TLS_INSTALL_LIB_PATH})

set(EDL_SEARCH_PATHS ${CMAKE_CURRENT_SOURCE_DIR}/../../src/include/edl)
endif()

include_directories(${INCLUDE_DIRS})
link_directories(${LIBRARY_DIRS})

set(E_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/sgx_stub_ecall.c)
set(EDLS ${CMAKE_CURRENT_SOURCE_DIR}/sgx_stub.edl)
set(LDS ${CMAKE_CURRENT_SOURCE_DIR}/sgx_stub_enclave.lds)
set(DEPEND_TRUSTED_LIBS crypto_wrapper_nullcrypto
crypto_wrapper_openssl
tls_wrapper_nulltls
tls_wrapper_openssl
attester_nullattester
attester_sgx_ecdsa
attester_sgx_la
verifier_nullverifier
verifier_sgx_la
verifier_sgx_ecdsa_qve
verifier_tdx_ecdsa
rats_tls
cbor
)

add_enclave_library(sgx_stub_enclave SRCS ${E_SRCS} EDL ${EDLS} TRUSTED_LIBS ${DEPEND_TRUSTED_LIBS} EDL_SEARCH_PATHS ${EDL_SEARCH_PATHS} LDSCRIPT ${LDS})
enclave_sign(sgx_stub_enclave KEY sgx_stub_enclave.pem CONFIG sgx_stub_enclave.xml)
add_dependencies(sgx_stub_enclave rats_tls)

install(FILES ${CMAKE_CURRENT_BINARY_DIR}/sgx_stub_enclave.signed.so
DESTINATION ${RATS_TLS_INSTALL_FUZZ_PATH})
32 changes: 32 additions & 0 deletions fuzz/sgx-stub-enclave/sgx_stub.edl
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
enclave {
include "rats-tls/api.h"
include "internal/core.h"
include "sgx_eid.h"

from "../../src/include/edl/rtls.edl" import *;
from "sgx_tsgxssl.edl" import *;

trusted {
public int ecall_client_startup(
rats_tls_log_level_t log_level,
[in, out] char *fuzz_conf_bytes,
[in, string] char *attester_type,
[in, string] char *verifier_type,
[in, string] char *tls_type,
[in, string] char *crypto_type,
unsigned long flags,
uint32_t s_ip,
uint16_t s_port
);

public int ecall_server_startup(
rats_tls_log_level_t log_level,
[in, string] char *attester_type,
[in, string] char *verifier_type,
[in, string] char *tls_type,
[in, string] char *crypto_type,
unsigned long flags,
uint32_t s_ip,
uint16_t s_port);
};
};
190 changes: 190 additions & 0 deletions fuzz/sgx-stub-enclave/sgx_stub_ecall.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#include <rats-tls/api.h>
#include <rats-tls/log.h>
#include "rats-tls/api.h"
#include "sgx_urts.h"
#include "sgx_stub_t.h"

#define FUZZ_IP "127.0.0.1"
#define FUZZ_PORT 1234

int ecall_client_startup(rats_tls_log_level_t log_level, char *fuzz_conf_bytes, char *attester_type,
char *verifier_type, char *tls_type, char *crypto_type,
unsigned long flags, uint32_t s_ip, uint16_t s_port)
{
rats_tls_conf_t conf;
memset(&conf, 0, sizeof(rats_tls_conf_t));

snprintf(conf.attester_type, sizeof(conf.attester_type), "%s", attester_type);
snprintf(conf.verifier_type, sizeof(conf.verifier_type), "%s", verifier_type);
snprintf(conf.tls_type, sizeof(conf.tls_type), "%s", tls_type);
snprintf(conf.crypto_type, sizeof(conf.crypto_type), "%s", crypto_type);
conf.flags = flags;
conf.cert_algo = RATS_TLS_CERT_ALGO_DEFAULT;

RTLS_INFO("Enter the client \n");

claim_t custom_claims[2] = {
{ .name = "key_0", .value = (uint8_t *)"value_0", .value_size = sizeof("value_0") },
{ .name = "key_1", .value = (uint8_t *)"value_1", .value_size = sizeof("value_1") },
};
conf.custom_claims = (claim_t *)custom_claims;
conf.custom_claims_length = 2;

/* Create a socket that uses an internet IPv4 address,
* Sets the socket to be stream based (TCP),
* 0 means choose the default protocol.
*/

int64_t sockfd;
int sgx_status = ocall_socket(&sockfd, RTLS_AF_INET, RTLS_SOCK_STREAM, 0);
if (sgx_status != SGX_SUCCESS || sockfd < 0) {
// RTLS_ERR("Failed to call socket() %#x %d\n", sgx_status, sockfd);
return -1;
}

struct rtls_sockaddr_in s_addr;
memset(&s_addr, 0, sizeof(s_addr));
s_addr.sin_family = RTLS_AF_INET;
s_addr.sin_addr.s_addr = s_ip;
s_addr.sin_port = s_port;

/* Connect to the server */
int ocall_ret = 0;
sgx_status = ocall_connect(&ocall_ret, sockfd, &s_addr, sizeof(s_addr));
if (sgx_status != SGX_SUCCESS || ocall_ret == -1) {
// RTLS_ERR("failed to call connect() %#x %d\n", sgx_status, ocall_ret);
return -1;
}

// RTLS_INFO("Enter the init \n");
/* rats-tls init */
librats_tls_init();
rats_tls_handle handle;
rats_tls_err_t ret = rats_tls_init(&conf, &handle);
if (ret != RATS_TLS_ERR_NONE) {
// RTLS_ERR("Failed to initialize rats tls %#x\n", ret);
return -1;
}
// RTLS_INFO("start to negotiate\n");

ret = rats_tls_negotiate(handle, (int)sockfd);
if (ret != RATS_TLS_ERR_NONE) {
// RTLS_ERR("Failed to negotiate %#x\n", ret);
return -1;
}

const char *msg = "Hello and welcome to RATS-TLS!\n";
size_t len = strlen(msg);
// RTLS_INFO("Enter the transmit \n");
ret = rats_tls_transmit(handle, (void *)msg, &len);
if (ret != RATS_TLS_ERR_NONE || len != strlen(msg)) {
// RTLS_ERR("Failed to transmit %#x\n", ret);
goto err;
}

ret = rats_tls_cleanup(handle);
if (ret != RATS_TLS_ERR_NONE)
// RTLS_ERR("Failed to cleanup %#x\n", ret);

return 0;

err:
rats_tls_cleanup(handle);
return -1;
}

int ecall_server_startup(rats_tls_log_level_t log_level, char *attester_type, char *verifier_type,
char *tls_type, char *crypto_type, unsigned long flags, uint32_t s_ip,
uint16_t s_port)
{
rats_tls_conf_t conf;
memset(&conf, 0, sizeof(conf));
conf.log_level = log_level;

snprintf(conf.attester_type, sizeof(conf.attester_type), "%s", attester_type);
snprintf(conf.verifier_type, sizeof(conf.verifier_type), "%s", verifier_type);
snprintf(conf.tls_type, sizeof(conf.tls_type), "%s", tls_type);
snprintf(conf.crypto_type, sizeof(conf.crypto_type), "%s", crypto_type);

conf.flags = flags;
conf.cert_algo = RATS_TLS_CERT_ALGO_DEFAULT;

claim_t custom_claims[2] = {
{ .name = "key_0", .value = (uint8_t *)"value_0", .value_size = sizeof("value_0") },
{ .name = "key_1", .value = (uint8_t *)"value_1", .value_size = sizeof("value_1") },
};
conf.custom_claims = (claim_t *)custom_claims;
conf.custom_claims_length = 2;

int64_t sockfd;
int sgx_status = ocall_socket(&sockfd, RTLS_AF_INET, RTLS_SOCK_STREAM, 0);
if (sgx_status != SGX_SUCCESS || sockfd < 0) {
// RTLS_ERR("Failed to call socket() %#x %d\n", sgx_status, sockfd);
return -1;
}

int ocall_ret = 0;

struct rtls_sockaddr_in s_addr;
memset(&s_addr, 0, sizeof(s_addr));
s_addr.sin_family = RTLS_AF_INET;
s_addr.sin_addr.s_addr = s_ip;
s_addr.sin_port = s_port;

/* Bind the server socket */
sgx_status = ocall_bind(&ocall_ret, sockfd, &s_addr, sizeof(s_addr));
if (sgx_status != SGX_SUCCESS || ocall_ret == -1) {
// RTLS_ERR("Failed to call bind(), %#x %d\n", sgx_status, ocall_ret);
return -1;
}

/* Listen for a new connection, allow 5 pending connections */
sgx_status = ocall_listen(&ocall_ret, sockfd, 5);
if (sgx_status != SGX_SUCCESS || ocall_ret == -1) {
// RTLS_ERR("Failed to call listen(), %#x %d\n", sgx_status, ocall_ret);
return -1;
}

librats_tls_init();
rats_tls_handle handle;
rats_tls_err_t ret = rats_tls_init(&conf, &handle);
if (ret != RATS_TLS_ERR_NONE) {
// RTLS_ERR("Failed to initialize rats tls %#x\n", ret);
return -1;
}

struct rtls_sockaddr_in c_addr;
uint32_t addrlen_in = sizeof(c_addr);
uint32_t addrlen_out;
while (1) {
// RTLS_INFO("Waiting for a connection ...\n");

int64_t connd;
sgx_status = ocall_accept(&connd, sockfd, &c_addr, addrlen_in, &addrlen_out);
if (sgx_status != SGX_SUCCESS || connd < 0) {
// RTLS_ERR("Failed to call accept() %#x %d\n", sgx_status, connd);
return -1;
}

ret = rats_tls_negotiate(handle, connd);
if (ret != RATS_TLS_ERR_NONE) {
// RTLS_ERR("Failed to negotiate %#x\n", ret);
goto err;
}

// RTLS_INFO("Client connected successfully\n");

ocall_close(&ocall_ret, connd);
}

return 0;
err:
/* Ignore the error code of cleanup in order to return the prepositional error */
rats_tls_cleanup(handle);
return -1;
}
3 changes: 3 additions & 0 deletions fuzz/sgx-stub-enclave/sgx_stub_ecall.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#ifndef _SGX_STUB_ECALL_H_
#define _SGX_STUB_ECALL_H_
#endif
Loading

0 comments on commit d427a4e

Please sign in to comment.