From 385757a535d8415ef080c80025215abb3ad6e494 Mon Sep 17 00:00:00 2001 From: "Ganyu (Bruce) Xu" Date: Sun, 10 Dec 2023 16:06:42 -0500 Subject: [PATCH 1/4] Marvin toolkit container --- marvin-toolkit/Cargo.toml | 13 ++++ marvin-toolkit/Dockerfile | 23 +++++++ marvin-toolkit/README.md | 10 +++ marvin-toolkit/entrypoint.sh | 127 +++++++++++++++++++++++++++++++++++ 4 files changed, 173 insertions(+) create mode 100644 marvin-toolkit/Cargo.toml create mode 100644 marvin-toolkit/Dockerfile create mode 100644 marvin-toolkit/README.md create mode 100644 marvin-toolkit/entrypoint.sh diff --git a/marvin-toolkit/Cargo.toml b/marvin-toolkit/Cargo.toml new file mode 100644 index 00000000..02f0cc1e --- /dev/null +++ b/marvin-toolkit/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "rust-crypto" +version = "0.1.0" +edition = "2021" + +[dependencies] +anyhow = "1" +clap = { version = "4", features = ["derive"] } +rsa = "0.9" + +[patch.crates-io] +rsa = { git = "https://github.com/xuganyu96/RSA", branch = "const-crypto-biguint" } +crypto-bigint = { git = "https://github.com/RustCrypto/crypto-bigint", branch = "master" } \ No newline at end of file diff --git a/marvin-toolkit/Dockerfile b/marvin-toolkit/Dockerfile new file mode 100644 index 00000000..afabec4f --- /dev/null +++ b/marvin-toolkit/Dockerfile @@ -0,0 +1,23 @@ +FROM python:3.12-bookworm + +# Create non-root user +RUN adduser rustcrypto --disabled-password --gecos "" + +USER rustcrypto + +# Install Rust +RUN curl -sSf https://sh.rustup.rs | sh -s -- -y +ENV PATH="/home/rustcrypto/.cargo/bin:${PATH}" + +# Clone the marvin-toolkit repository +RUN cd $HOME \ + && git clone https://github.com/tomato42/marvin-toolkit.git \ + && cd marvin-toolkit \ + && chmod +x *.sh \ + && ./step0.sh +WORKDIR "/home/rustcrypto/marvin-toolkit" + +# Generating private keys, ciphertexts, building RustCrypto/RSA, should all be done at runtime +COPY --chmod=777 entrypoint.sh ./entrypoint.sh + +ENTRYPOINT ["./entrypoint.sh"] \ No newline at end of file diff --git a/marvin-toolkit/README.md b/marvin-toolkit/README.md new file mode 100644 index 00000000..4e5026bb --- /dev/null +++ b/marvin-toolkit/README.md @@ -0,0 +1,10 @@ +# Marvin tool-kit integration +This document describes the procedure for replicating the analysis for the Marvin attack. This analysis is best done on a container for reproducibility. + +```bash +docker build -t marvin:latest . +docker run --rm \ + --name marvin \ + -v /home/ec2-user/RSA/marvin-toolkit/Cargo.toml:/home/rustcrypto/marvin-toolkit/example/rust-crypto/Cargo.toml \ + marvin:latest +``` diff --git a/marvin-toolkit/entrypoint.sh b/marvin-toolkit/entrypoint.sh new file mode 100644 index 00000000..f4327e27 --- /dev/null +++ b/marvin-toolkit/entrypoint.sh @@ -0,0 +1,127 @@ +#!/bin/bash + +# Build the test harness +cd example/rust-crypto +cargo update +cargo build --profile release +cd ~/marvin-toolkit + +# Parse CLI inputs to $size and $repeat +size=2048 +repeat=100000 + +# Function to display help message +display_help() { + echo "Usage: $0 [-s SIZE] [-n NUMBER] [-h]" + echo " -s SIZE Set the RSA key size (1024, 2048, or 4096; default: 2048)" + echo " -n NUMBER Set the repeat number (integer; default: 100000)" + echo " -h Display this help message" +} + +# Parse command-line arguments using getopts +while getopts ":s:n:h" opt; do + case $opt in + s) + size=$OPTARG + if [[ ! "$size" =~ ^(1024|2048|4096)$ ]]; then + echo "Error: Invalid size. Please choose 1024, 2048, or 4096." + exit 1 + fi + ;; + n) + repeat=$OPTARG + if ! [[ "$repeat" =~ ^[0-9]+$ ]]; then + echo "Error: Invalid number. Please specify a valid integer." + exit 1 + fi + ;; + h) + display_help + exit 0 + ;; + \?) + echo "Error: Invalid option -$OPTARG" + display_help + exit 1 + ;; + :) + echo "Error: Option -$OPTARG requires an argument." + display_help + exit 1 + ;; + esac +done +size_bytes=$(($size / 8)) + +# Step 1: Generate key pairs +. ./certgen/certgen/lib.sh +name="rsa${size}" +tmp_file="$(mktemp)" +if ! x509KeyGen -s $size $name &> "$tmp_file"; then + echo "ERROR $size bit key generation failed" >&2 + cat "$tmp_file" >&2 + exit 1 +fi +if ! x509SelfSign $name &> "$tmp_file"; then + echo "ERROR: $size bit key self-signing failed" >&2 + cat "$tmp_file" >&2 + exit 1 +fi + +echo "RSA $size bit private key in old OpenSSL PEM format is in" $(x509Key $name) +echo "RSA $size bit private key in old OpenSSL DER format is in" $(x509Key --der $name) +echo "RSA $size bit private key in PKCS#8 PEM format is in" $(x509Key --pkcs8 $name) +echo "RSA $size bit private key in PKCS#8 DER format is in" $(x509Key --der --pkcs8 $name) +echo "RSA $size bit private key in PKCS#12 format is in" $(x509Key --with-cert --pkcs12 $name) +echo "RSA $size bit self-signed certificate is in" $(x509Cert $name) +echo + +# Generate ciphertexts +case $size in + 1024) + PYTHONPATH=tlsfuzzer ./marvin-venv/bin/python ./step2.py \ + -c rsa1024/cert.pem -o rsa1024_repeat \ + --repeat ${repeat} --verbose \ + no_structure no_padding=48 signature_padding=8 \ + valid_repeated_byte_payload="118 0xff" \ + valid_repeated_byte_payload="118 0x01" \ + valid=48 header_only \ + no_header_with_payload=48 zero_byte_in_padding="48 4" \ + valid=0 valid=118 + ;; + 2048) + PYTHONPATH=tlsfuzzer ./marvin-venv/bin/python ./step2.py \ + -c rsa2048/cert.pem -o rsa2048_repeat \ + --repeat ${repeat} --verbose \ + no_structure no_padding=48 signature_padding=8 \ + valid_repeated_byte_payload="246 0xff" \ + valid_repeated_byte_payload="246 0x01" \ + valid=48 header_only \ + no_header_with_payload=48 zero_byte_in_padding="48 4" \ + valid=0 valid=192 valid=246 + ;; + 4096) + PYTHONPATH=tlsfuzzer ./marvin-venv/bin/python ./step2.py \ + -c rsa4096/cert.pem -o rsa4096_repeat \ + --repeat ${repeat} --verbose \ + no_structure no_padding=48 signature_padding=8 \ + valid_repeated_byte_payload="502 0xff" \ + valid_repeated_byte_payload="502 0x01" \ + valid=48 header_only \ + no_header_with_payload=48 zero_byte_in_padding="48 4" \ + valid=0 valid=192 valid=502 + ;; +esac + +# Run decryptions and analyze data +echo "Starting decryption" +./example/rust-crypto/target/release/rust-crypto \ + -i rsa${size}_repeat/ciphers.bin \ + -o rsa${size}_repeat/raw_times.csv -k rsa${size}/pkcs8.pem -n $size_bytes +echo "Decryptions finished" +PYTHONPATH=tlsfuzzer marvin-venv/bin/python3 tlsfuzzer/tlsfuzzer/extract.py \ +-l rsa${size}_repeat/log.csv --raw-times rsa${size}_repeat/raw_times.csv \ +-o rsa${size}_repeat/ \ +--clock-frequency 1000 +PYTHONPATH=tlsfuzzer marvin-venv/bin/python3 tlsfuzzer/tlsfuzzer/analysis.py \ +-o rsa${size}_repeat/ --verbose \ No newline at end of file From edb379fe6d91d3d65d15c51ea226b2e3e0dad525 Mon Sep 17 00:00:00 2001 From: "Ganyu (Bruce) Xu" Date: Mon, 11 Dec 2023 23:30:48 -0500 Subject: [PATCH 2/4] Additional documentation; copy results --- marvin-toolkit/Cargo.toml | 2 +- marvin-toolkit/README.md | 50 ++++++++++++++++++++++++++++++++++-- marvin-toolkit/entrypoint.sh | 8 +++++- 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/marvin-toolkit/Cargo.toml b/marvin-toolkit/Cargo.toml index 02f0cc1e..7ad3142b 100644 --- a/marvin-toolkit/Cargo.toml +++ b/marvin-toolkit/Cargo.toml @@ -9,5 +9,5 @@ clap = { version = "4", features = ["derive"] } rsa = "0.9" [patch.crates-io] -rsa = { git = "https://github.com/xuganyu96/RSA", branch = "const-crypto-biguint" } +rsa = { git = "https://github.com/RustCrypto/RSA", branch = "const-crypto-biguint" } crypto-bigint = { git = "https://github.com/RustCrypto/crypto-bigint", branch = "master" } \ No newline at end of file diff --git a/marvin-toolkit/README.md b/marvin-toolkit/README.md index 4e5026bb..58ca1338 100644 --- a/marvin-toolkit/README.md +++ b/marvin-toolkit/README.md @@ -1,10 +1,56 @@ # Marvin tool-kit integration This document describes the procedure for replicating the analysis for the Marvin attack. This analysis is best done on a container for reproducibility. +**TL;DR**: ```bash docker build -t marvin:latest . -docker run --rm \ + +# Compile RustCrypto/RSA 0.9 then Run the analysis using RSA 2048 and with +# 100000 repeat +docker run -d --rm \ + --name marvin \ + marvin:latest + +# Use "docker logs -f marvin" to read live output +``` + +## Adjusting analysis parameters +For more help on the options pass in the `-h` flag in the `docker run` command: + +``` +docker run ... marvin:latest -h +``` + +There are two main parameters of the analysis: RSA key size and the number of repetitions during ciphertext generation. + +RSA key size is specified through `-s <1024|2048|4096>`. The number of repetition is specified through `-n `. A larger repetition number will increase the confidence of the analysis, but will make the analysis take longer. The default key size is 2048 and the default repetition count is 100,000. + +```bash +# Run analysis for RSA 4096 with 1 million repetition +docker run -d --rm \ --name marvin \ - -v /home/ec2-user/RSA/marvin-toolkit/Cargo.toml:/home/rustcrypto/marvin-toolkit/example/rust-crypto/Cargo.toml \ + marvin:latest -s 4096 -n 1000000 +``` + +## Extracting keys, ciphertexts, and analysis results (WIP) +After the analysis is done, the generate keys, ciphertexts, and the analysis outputs are all copied into the directory `/home/rustcrypto/marvin-toolkit/outputs`. To extract and preserve these artifacts, mount a volume into this directory, such as using a bind mount: + +```bash +HOST_OUTPUT_DIR="..." +mkdir -p ${HOST_OUTPUT_DIR} +chmod a+rw ${HOST_OUTPUT_DIR} + +# Mount +docker run -d --rm --name "marvin" \ + -v ${HOST_OUTPUT_DIR}:/home/rustcrypto/marvin-toolkit/outputs \ marvin:latest ``` + +## Compile test harness with custom `Cargo.toml` +The test harness is compiled at container run-time, so a custom `Cargo.toml` can be passed into the container at runtime to compile the test harness using custom versions of `RustCrypto/RSA` and/or `RustCrypto/crypto-bigint`: + +```bash +docker run -d --rm --name "marvin" \ + -v /host/path/Cargo.toml:/home/rustcrypto/marvin-toolkit/example/rust-crypto/Cargo.toml \ + marvin:latest +``` \ No newline at end of file diff --git a/marvin-toolkit/entrypoint.sh b/marvin-toolkit/entrypoint.sh index f4327e27..a874c67f 100644 --- a/marvin-toolkit/entrypoint.sh +++ b/marvin-toolkit/entrypoint.sh @@ -124,4 +124,10 @@ PYTHONPATH=tlsfuzzer marvin-venv/bin/python3 tlsfuzzer/tlsfuzzer/extract.py \ -o rsa${size}_repeat/ \ --clock-frequency 1000 PYTHONPATH=tlsfuzzer marvin-venv/bin/python3 tlsfuzzer/tlsfuzzer/analysis.py \ --o rsa${size}_repeat/ --verbose \ No newline at end of file +-o rsa${size}_repeat/ --verbose + +# Copy over the keys and the results, if the results directory exists +if [[ -d ~/marvin-toolkit/outputs ]]; then + copy -r rsa${size} ~/marvin-toolkit/outputs/keys + copy -r rsa${size}_repeat ~/marvin-toolkit/outputs/results +fi \ No newline at end of file From 52846c336b4ba0ac46559789d131806211132ca2 Mon Sep 17 00:00:00 2001 From: "Ganyu (Bruce) Xu" Date: Mon, 11 Dec 2023 23:41:15 -0500 Subject: [PATCH 3/4] Fixed minor typo in command; fuller TL;DR --- marvin-toolkit/README.md | 26 ++++++++++++++++++-------- marvin-toolkit/entrypoint.sh | 4 ++-- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/marvin-toolkit/README.md b/marvin-toolkit/README.md index 58ca1338..aa54b3d7 100644 --- a/marvin-toolkit/README.md +++ b/marvin-toolkit/README.md @@ -3,15 +3,24 @@ This document describes the procedure for replicating the analysis for the Marvi **TL;DR**: ```bash +# Build the image docker build -t marvin:latest . -# Compile RustCrypto/RSA 0.9 then Run the analysis using RSA 2048 and with -# 100000 repeat +# Create the output directory and allow container to write to it +mkdir -p outputs +chmod a+rw outputs + +# Run the analysis docker run -d --rm \ --name marvin \ + -v $(pwd)/outputs:/home/rustcrypto/marvin-toolkit/outputs \ + -v $(pwd)/Cargo.toml:/home/rustcrypto/marvin-toolkit/example/rust-crypto/Cargo.toml \ marvin:latest # Use "docker logs -f marvin" to read live output + +# Read the output +cat outputs/results/report.txt ``` ## Adjusting analysis parameters @@ -36,13 +45,12 @@ docker run -d --rm \ After the analysis is done, the generate keys, ciphertexts, and the analysis outputs are all copied into the directory `/home/rustcrypto/marvin-toolkit/outputs`. To extract and preserve these artifacts, mount a volume into this directory, such as using a bind mount: ```bash -HOST_OUTPUT_DIR="..." -mkdir -p ${HOST_OUTPUT_DIR} -chmod a+rw ${HOST_OUTPUT_DIR} +mkdir -p outputs +chmod a+rw outputs # Mount docker run -d --rm --name "marvin" \ - -v ${HOST_OUTPUT_DIR}:/home/rustcrypto/marvin-toolkit/outputs \ + -v $(pwd)/outputs:/home/rustcrypto/marvin-toolkit/outputs \ marvin:latest ``` @@ -51,6 +59,8 @@ The test harness is compiled at container run-time, so a custom `Cargo.toml` can ```bash docker run -d --rm --name "marvin" \ - -v /host/path/Cargo.toml:/home/rustcrypto/marvin-toolkit/example/rust-crypto/Cargo.toml \ + -v $(pwd)/Cargo.toml:/home/rustcrypto/marvin-toolkit/example/rust-crypto/Cargo.toml \ marvin:latest -``` \ No newline at end of file +``` + +If no `Cargo.toml` is specified, the default one will use `rsa = 0.9` \ No newline at end of file diff --git a/marvin-toolkit/entrypoint.sh b/marvin-toolkit/entrypoint.sh index a874c67f..ce5d872a 100644 --- a/marvin-toolkit/entrypoint.sh +++ b/marvin-toolkit/entrypoint.sh @@ -128,6 +128,6 @@ PYTHONPATH=tlsfuzzer marvin-venv/bin/python3 tlsfuzzer/tlsfuzzer/analysis.py \ # Copy over the keys and the results, if the results directory exists if [[ -d ~/marvin-toolkit/outputs ]]; then - copy -r rsa${size} ~/marvin-toolkit/outputs/keys - copy -r rsa${size}_repeat ~/marvin-toolkit/outputs/results + cp -r rsa${size} ~/marvin-toolkit/outputs/keys + cp -r rsa${size}_repeat ~/marvin-toolkit/outputs/results fi \ No newline at end of file From fa961bb4212272cdb7e2e3e34e3e2b01aa3b9131 Mon Sep 17 00:00:00 2001 From: "Ganyu (Bruce) Xu" Date: Mon, 11 Dec 2023 23:44:31 -0500 Subject: [PATCH 4/4] cargo quiently --- marvin-toolkit/entrypoint.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/marvin-toolkit/entrypoint.sh b/marvin-toolkit/entrypoint.sh index ce5d872a..3f71564e 100644 --- a/marvin-toolkit/entrypoint.sh +++ b/marvin-toolkit/entrypoint.sh @@ -2,8 +2,8 @@ # Build the test harness cd example/rust-crypto -cargo update -cargo build --profile release +cargo update --quiet +cargo build --profile release --quiet cd ~/marvin-toolkit # Parse CLI inputs to $size and $repeat