Skip to content

Commit

Permalink
fuzz/*: fuzz rats-tls APIs in host mode
Browse files Browse the repository at this point in the history
use libfuzzer to fuzz rats-tls API `rats_tls_init()`,
,`rats_tls_transmit()` and
 `rats_tls_receive()` in host mode. fuzz for rats_tls_negotiate()
has some bugs, it would be fixed and committed later.

Signed-off-by: Pengyu Chen <[email protected]>
  • Loading branch information
Ben-cpy committed Sep 26, 2023
1 parent 7e2fd97 commit 0d35ab1
Show file tree
Hide file tree
Showing 9 changed files with 597 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)
60 changes: 60 additions & 0 deletions fuzz/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# 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
```
25 changes: 25 additions & 0 deletions fuzz/tls_init/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
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 -fPIE ${CMAKE_CXX_FLAGS}")

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_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})
113 changes: 113 additions & 0 deletions fuzz/tls_init/fuzz_init.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/* 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);

// free memory
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;
}
26 changes: 26 additions & 0 deletions fuzz/tls_server/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
project(fuzz_server CXX)

set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
set(CMAKE_CXX_COMPILER "/usr/bin/clang++")
set(CMAKE_CXX_FLAGS "-g ${CMAKE_CXX_FLAGS}")

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_server.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 0d35ab1

Please sign in to comment.