Skip to content

Commit

Permalink
fuzz/*: fuzz rats-tls APIs in host mode (#183)
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()`
and`rats_tls_receive()` in host mode

Signed-off-by: Pengyu Chen <[email protected]>
  • Loading branch information
Ben-cpy authored Oct 30, 2023
1 parent 7e2fd97 commit 190181b
Show file tree
Hide file tree
Showing 11 changed files with 840 additions and 0 deletions.
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ list(GET VERSION_LIST 2 VERSION_PATCH)
option(BUILD_SAMPLES "Compile sample code along with libraries" ON)
option(SGX_HW "Run SGX on hardware, OFF for simulation" ON)
option(SGX_LVI_MITIGATION "Mitigation flag, default on" ON)
option(BUILD_FUZZ "Use lib-fuzzer to fuzz the code, default OFF" OFF)

# Define build mode
set(RATS_TLS_BUILD_MODE "host"
Expand Down Expand Up @@ -102,6 +103,11 @@ if(BUILD_SAMPLES)
add_subdirectory(samples)
endif()

if(BUILD_FUZZ)
message(STATUS "Build Fuzz: on")
add_subdirectory(fuzz)
endif()

# Uninstall target
if(NOT TARGET uninstall)
configure_file(
Expand Down
4 changes: 4 additions & 0 deletions fuzz/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
add_subdirectory(tls_init)
add_subdirectory(tls_negotiate)
add_subdirectory(tls_server)
add_subdirectory(tls_transmit)
68 changes: 68 additions & 0 deletions fuzz/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Building

## Build Requirements

Note that `LibFuzzer` is part of `clang`, LibFuzzer is an in-process, coverage-guided, evolutionary fuzzing engine.
`LibFuzzer` is linked with the library under test, and feeds fuzzed inputs to the library via a specific fuzzing entrypoint (aka “target function”); the fuzzer then tracks which areas of the code are reached, and generates mutations on the corpus of input data in order to maximize the code coverage.

Follow these steps to install clang:
+ Debian / Ubuntu:

```shell
apt install -y clang
```

+ CentOS / RHEL / Fedora:

```shell
yum install -y clang
```

## Build and Install

To build fuzzer program, just add `-DBUILD_FUZZ=on` option is enough, then you would see fuzz program in `/usr/share/rats-tls/fuzz`.

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

# FUZZ

## rats_tls_init API

To fuzz `rats_tls_init()`, we use random input `* data` to fill the `conf`, and set value to part of the `conf` in order to run `rats_tls_init()` more frequently.

```bash
cd /usr/share/rats-tls/fuzz/
mkdir corpus && cd corpus # create corpus dir
base64 /dev/urandom | head -c 1500000 > c1 # fill in corpus with random string
cd ..
./fuzz_init -max_len=1500000 -len_control=0 corpus # len_control=0 means try genarating input with size up to max_len
```

## rats_tls_negotiate API

Start the `/usr/share/rats_tls/fuzz/fuzz_server` first, then use `tls_negotiate` to connect to server and fuzz the `rats_tls_negotiate()` API.

```bash
cd /usr/share/rats_tls/fuzz/
mkdir corpus && cd corpus # create corpus dir
base64 /dev/urandom | head -c 1500000 > c1 # fill in corpus with random string
cd ..
./fuzz_server &
./fuzz_negotiate -max_len=1500000 -len_control=0 corpus # len_control=0 means try genarating input with size up to max_len
```

## rats_tls_transmit / rats_tls_recv / rats_tls_cleanup

We synthesis the 3 sequential API in one program, start the `/usr/share/rats_tls/fuzz/fuzz_server` first, then use `tls_transmit` to connect to server and fuzz the `rats_tls_transmit()` and `rats_tls_recv()`,`rats_tls_cleanup` APIs by sending ramdom string and receiving the same response.

```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_transmit -max_len=1500000 -len_control=0 corpus # len_control=0 means try genarating input with size up to max_len
```
28 changes: 28 additions & 0 deletions fuzz/tls_init/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
project(fuzz_init CXX)

set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
set(CMAKE_CXX_COMPILER "/usr/bin/clang++")
set(CMAKE_CXX_FLAGS "-fsanitize=address,fuzzer -g ${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS "-fPIE ${CMAKE_CXX_FLAGS}")
set(RATS_TLS_INSTALL_FUZZ_PATH /usr/share/rats-tls/fuzz)

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

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

# Set source file
set(SOURCES fuzz_init.cc)

# Generate bin file
add_executable(${PROJECT_NAME} ${SOURCES})
target_link_libraries(${PROJECT_NAME} rats_tls)

install(TARGETS ${PROJECT_NAME}
DESTINATION ${RATS_TLS_INSTALL_FUZZ_PATH})
112 changes: 112 additions & 0 deletions fuzz/tls_init/fuzz_init.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/* Copyright (c) 2021 Intel Corporation
* Copyright (c) 2020-2021 Alibaba Cloud
*
* SPDX-License-Identifier: Apache-2.0
*/
extern "C" {
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include "rats-tls/api.h"
#include "rats-tls/log.h"
#include "rats-tls/claim.h"
#include "internal/core.h"
}
#include <fuzzer/FuzzedDataProvider.h>
#include <vector>

#define CUSTOM_CLAIMS_SIZE 10

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
rats_tls_conf_t conf; // consume 192 bytes
if (size < sizeof(rats_tls_conf_t) + 10 * sizeof(claim_t) + 50 * 10 + 100) {
return 0;
}
FuzzedDataProvider fuzzed_data(data + sizeof(conf), size - sizeof(conf));

char attester_types[10][25] = { "nullattester", "", "sgx_la", "csv",
"sev", "sev_snp", "tdx_ecdsa", "sgx_ecdsa" };
strcpy(attester_types[8], fuzzed_data.ConsumeBytesWithTerminator(20, '\0').data());
if (fuzzed_data.remaining_bytes() < 0) {
return 0;
}
for (int i = 0; i < 9; i++) {
char verifier_types[10][25] = { "nullverifier", "", "sgx_la",
"csv", "sev", "sev_snp",
"tdx_ecdsa", "tdx_ecdsa", "sgx_ecdsa_qve" };
strcpy(verifier_types[9], fuzzed_data.ConsumeBytesWithTerminator(20, '\0').data());
if (fuzzed_data.remaining_bytes() < 0) {
return 0;
}
for (int j = 0; j < 10; j++) {
char tls_types[4][25] = { "nulltls", "", "openssl" };
strcpy(tls_types[3],
fuzzed_data.ConsumeBytesWithTerminator(20, '\0').data());
if (fuzzed_data.remaining_bytes() < 0) {
return 0;
}
for (int k = 0; k < 4; k++) {
char crypto_types[4][25] = { "nullcrypto", "", "openssl" };
strcpy(crypto_types[3],
fuzzed_data.ConsumeBytesWithTerminator(20, '\0').data());
if (fuzzed_data.remaining_bytes() < 0) {
return 0;
}
for (int l = 0; l < 4; l++) {
memcpy(&conf,
fuzzed_data.ConsumeBytes<uint8_t>(sizeof(conf))
.data(),
sizeof(conf));
conf.log_level = RATS_TLS_LOG_LEVEL_DEFAULT;
conf.api_version = 0;

strcpy(conf.attester_type, attester_types[i]);
strcpy(conf.verifier_type, verifier_types[j]);
strcpy(conf.tls_type, tls_types[k]);
strcpy(conf.crypto_type, crypto_types[l]);

conf.cert_algo = RATS_TLS_CERT_ALGO_DEFAULT;
conf.flags = fuzzed_data.ConsumeIntegral<long>();

claim_t custom_claims[CUSTOM_CLAIMS_SIZE];
std::vector<std::string> str_lists;
for (int c = 0; c < CUSTOM_CLAIMS_SIZE; c++) {
std::vector<char> vec_str =
fuzzed_data.ConsumeBytesWithTerminator(
50, '\0');
std::string str(vec_str.begin(), vec_str.end());
str_lists.push_back(str);
custom_claims[c].value =
(uint8_t *)str_lists[c].c_str();
custom_claims[c].value_size =
(strlen(str_lists[c].c_str()) + 1) *
sizeof(char);
if (fuzzed_data.remaining_bytes() <= 0) {
for (int p = 0; p < c; p++) {
free(custom_claims[p].name);
}
return 0;
}
custom_claims[c].name = (char *)malloc(15);
strcpy(custom_claims[c].name,
fuzzed_data.ConsumeBytesAsString(10).c_str());
}
conf.custom_claims = (claim_t *)custom_claims;
conf.custom_claims_length = CUSTOM_CLAIMS_SIZE;
rats_tls_handle handle;
rats_tls_err_t err = rats_tls_init(&conf, &handle);

for (int c = 0; c < CUSTOM_CLAIMS_SIZE; c++) {
free(custom_claims[c].name);
}
err = rats_tls_cleanup(handle);
if (err != RATS_TLS_ERR_NONE)
RTLS_ERR("Failed to cleanup %#x\n", err);
}
}
}
}

return 0;
}
29 changes: 29 additions & 0 deletions fuzz/tls_negotiate/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
project(fuzz_negotiate CXX)

set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
set(CMAKE_CXX_COMPILER "/usr/bin/clang++")
set(CMAKE_CXX_FLAGS "-fsanitize=address,fuzzer -g ${CMAKE_CXX_FLAGS}")
if(NOT SGX)
set(CMAKE_CXX_FLAGS "-fPIE ${CMAKE_CXX_FLAGS}")
endif()

set(INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../../src/include
${CMAKE_CURRENT_SOURCE_DIR}/../../src/include/rats-tls
${RATS_TLS_INSTALL_INCLUDE_PATH}
)
set(LIBRARY_DIRS ${RATS_TLS_INSTALL_LIB_PATH})
set(RATS_TLS_INSTALL_FUZZ_PATH /usr/share/rats-tls/fuzz)

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

# Set source file
set(SOURCES fuzz_negotiate.cc)

# Generate bin file
add_executable(${PROJECT_NAME} ${SOURCES})
target_link_libraries(${PROJECT_NAME} rats_tls)

install(TARGETS ${PROJECT_NAME}
DESTINATION ${RATS_TLS_INSTALL_FUZZ_PATH})

Loading

0 comments on commit 190181b

Please sign in to comment.