diff --git a/.github/workflows/simple.yml b/.github/workflows/simple.yml index 44324233..c02a358a 100644 --- a/.github/workflows/simple.yml +++ b/.github/workflows/simple.yml @@ -15,30 +15,52 @@ concurrency: jobs: make_check: + runs-on: ubuntu-latest + timeout-minutes: 20 + strategy: matrix: - config: [ - # Add new configs here - '', - 'OPENSSL_TAG=master', - 'WOLFSSL_TAG=master', - 'OPENSSL_TAG=master WOLFSSL_TAG=master', - ] - name: make check - runs-on: ubuntu-latest - # This should be a safe limit for the tests to run. - timeout-minutes: 10 + config: + - '' + - 'OPENSSL_TAG=master' + - 'WOLFSSL_TAG=master' + - 'OPENSSL_TAG=master WOLFSSL_TAG=master' + force_fail: + - '' + - 'WOLFPROV_FORCE_FAIL=1' + steps: - uses: actions/checkout@v4 - name: Checkout wolfProvider + name: Checkout repository - - name: Test wolfProvider + - name: Run build and tests run: | - ${{ matrix.config }} ./scripts/build-wolfprovider.sh + # Build first with matrix config + ${{ matrix.config }} ${{ matrix.force_fail }} ./scripts/build-wolfprovider.sh || BUILD_RESULT=$? - - name: Print errors - if: ${{ failure() }} + # Run all tests regardless of build result + ${{ matrix.force_fail }} ./scripts/cmd_test/do-cmd-tests.sh || TEST_RESULT=$? + + # For force_fail, we expect failures (return 1) + if [ -n "${{ matrix.force_fail }}" ]; then + if [ $BUILD_RESULT -eq 0 ] || [ $TEST_RESULT -eq 0 ]; then + echo "Build/Test unexpectedly succeeded with force fail enabled" + exit 1 # failure was not seen when expected + else + echo "Build/Test failed as expected with force fail enabled" + exit 0 # expected failure occurred + fi + else + # Normal case - expect success + if [ $BUILD_RESULT -ne 0 ] || [ $TEST_RESULT -ne 0 ]; then + exit 1 # unexpected failure + fi + fi + + - name: Print test logs + if: always() run: | if [ -f test-suite.log ] ; then cat test-suite.log fi + diff --git a/.github/workflows/socat.yml b/.github/workflows/socat.yml index 41ec70c9..efc1bbff 100644 --- a/.github/workflows/socat.yml +++ b/.github/workflows/socat.yml @@ -130,4 +130,4 @@ jobs: ./socat -V # Run the tests with expected failures - SOCAT=$GITHUB_WORKSPACE/socat-1.8.0.0/socat ./test.sh -t 0.5 --expect-fail 146,216,309,310,399,467,468,478,491,528 + SOCAT=$GITHUB_WORKSPACE/socat-1.8.0.0/socat ./test.sh -t 0.5 --expect-fail 36,64,146,214,216,217,309,310,386,399,402,403,459,460,467,468,475,478,491,492,528,529,530 diff --git a/README.md b/README.md index aeebf485..f3628e28 100644 --- a/README.md +++ b/README.md @@ -123,12 +123,17 @@ make check ## Testing ### Unit Tests -To run automated unit tests: +To run automated unit tests: * `make test` +### Command Tests + +To run the command tests: +* `./scripts/cmd_test/do-cmd-tests.sh` + ### Integration Tests To run the cipher suite testing: -* ./scripts/test-wp-cs.sh +* `./scripts/test-wp-cs.sh` diff --git a/scripts/cmd_test/aes-cmd-test.sh b/scripts/cmd_test/aes-cmd-test.sh new file mode 100755 index 00000000..1737022c --- /dev/null +++ b/scripts/cmd_test/aes-cmd-test.sh @@ -0,0 +1,131 @@ +#!/bin/bash + +# Set up environment +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +REPO_ROOT="$( cd "${SCRIPT_DIR}/../.." &> /dev/null && pwd )" +UTILS_DIR="${REPO_ROOT}/scripts" +export LOG_FILE="${SCRIPT_DIR}/aes-test.log" +touch "$LOG_FILE" + +# Source wolfProvider utilities +source "${UTILS_DIR}/utils-general.sh" +source "${UTILS_DIR}/utils-openssl.sh" +source "${UTILS_DIR}/utils-wolfssl.sh" +source "${UTILS_DIR}/utils-wolfprovider.sh" + +# Initialize the environment +init_wolfprov + +# Fail flag +FAIL=0 + +# Verify wolfProvider is properly loaded +echo -e "\nVerifying wolfProvider configuration:" +if ! $OPENSSL_BIN list -providers | grep -q "wolf"; then + echo "[FAIL] wolfProvider not found in OpenSSL providers!" + echo "Current provider list:" + $OPENSSL_BIN list -providers + FAIL=1 +else + echo "[PASS] wolfProvider is properly configured" +fi + +# Print environment for verification +echo "Environment variables:" +echo "OPENSSL_MODULES: ${OPENSSL_MODULES}" +echo "LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}" +echo "OPENSSL_BIN: ${OPENSSL_BIN}" + +# Create test data and output directories +mkdir -p aes_outputs +echo "This is test data for AES encryption testing." > test.txt + +# Arrays for test configurations +KEY_SIZES=("128" "192" "256") +# Only include modes supported by wolfProvider +MODES=("ecb" "cbc" "ctr" "cfb") + +echo "=== Running AES Algorithm Comparisons ===" + +# Run tests for each key size and mode +for key_size in "${KEY_SIZES[@]}"; do + for mode in "${MODES[@]}"; do + echo -e "\n=== Testing AES-${key_size}-${mode} ===" + + # Generate random key and IV + key=$($OPENSSL_BIN rand -hex $((key_size/8))) + iv="" + if [ "$mode" != "ecb" ]; then + iv="-iv $($OPENSSL_BIN rand -hex 16)" + fi + + # Output files + enc_file="aes_outputs/aes${key_size}_${mode}.enc" + dec_file="aes_outputs/aes${key_size}_${mode}.dec" + + # Interop testing: Encrypt with default provider, decrypt with wolfProvider + echo "Interop testing (encrypt with default, decrypt with wolfProvider):" + + # Encryption with OpenSSL default provider + if ! $OPENSSL_BIN enc -aes-${key_size}-${mode} -K $key $iv -provider default \ + -in test.txt -out "$enc_file" -p; then + echo "[FAIL] Interop AES-${key_size}-${mode}: OpenSSL encrypt failed" + FAIL=1 + fi + + # Decryption with wolfProvider + if ! $OPENSSL_BIN enc -aes-${key_size}-${mode} -K $key $iv -provider-path $WOLFPROV_PATH -provider libwolfprov \ + -in "$enc_file" -out "$dec_file" -d -p; then + echo "[FAIL] Interop AES-${key_size}-${mode}: wolfProvider decrypt failed" + FAIL=1 + fi + + if [ $FAIL -eq 0 ]; then + if cmp -s "test.txt" "$dec_file"; then + echo "[PASS] Interop AES-${key_size}-${mode}: OpenSSL encrypt, wolfProvider decrypt" + else + echo "[FAIL] Interop AES-${key_size}-${mode}: OpenSSL encrypt, wolfProvider decrypt" + FAIL=1 + fi + else + echo "[INFO] Cannot verify encryption/decryption - no key available" + fi + + # Interop testing: Encrypt with wolfProvider, decrypt with default provider + echo "Interop testing (encrypt with wolfProvider, decrypt with default):" + + # Encryption with wolfProvider + if ! $OPENSSL_BIN enc -aes-${key_size}-${mode} -K $key $iv -provider-path $WOLFPROV_PATH -provider libwolfprov \ + -in test.txt -out "$enc_file" -p; then + echo "[FAIL] Interop AES-${key_size}-${mode}: wolfProvider encrypt failed" + FAIL=1 + fi + + # Decryption with OpenSSL default provider + if ! $OPENSSL_BIN enc -aes-${key_size}-${mode} -K $key $iv -provider default \ + -in "$enc_file" -out "$dec_file" -d -p; then + echo "[FAIL] Interop AES-${key_size}-${mode}: OpenSSL decrypt failed" + FAIL=1 + fi + + if [ $FAIL -eq 0 ]; then + if cmp -s "test.txt" "$dec_file"; then + echo "[PASS] Interop AES-${key_size}-${mode}: wolfProvider encrypt, OpenSSL decrypt" + else + echo "[FAIL] Interop AES-${key_size}-${mode}: wolfProvider encrypt, OpenSSL decrypt" + FAIL=1 + fi + else + echo "[INFO] Cannot verify encryption/decryption - no key available" + fi + done +done + +# Change end of script to check FAIL flag +if [ $FAIL -eq 0 ]; then + echo -e "\n=== All AES tests completed successfully ===" + exit 0 +else + echo -e "\n=== AES tests completed with failures ===" + exit 1 +fi diff --git a/scripts/cmd_test/do-cmd-tests.sh b/scripts/cmd_test/do-cmd-tests.sh new file mode 100755 index 00000000..ff18d8ad --- /dev/null +++ b/scripts/cmd_test/do-cmd-tests.sh @@ -0,0 +1,83 @@ +#!/bin/bash +# do-cmd-tests.sh +# Run all command-line tests for wolfProvider +# +# Copyright (C) 2006-2024 wolfSSL Inc. +# +# This file is part of wolfProvider. +# +# wolfProvider is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# wolfProvider is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + +# Get the directory where this script is located +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +REPO_ROOT="$( cd "${SCRIPT_DIR}/../.." &> /dev/null && pwd )" +UTILS_DIR="${REPO_ROOT}/scripts" + +# Get the built versions +if [ -d "${REPO_ROOT}/openssl-source" ] && [ -d "${REPO_ROOT}/wolfssl-source" ]; then + # Get the actual versions that were built + export OPENSSL_TAG=$(cd ${REPO_ROOT}/openssl-source && + (git describe --tags 2>/dev/null || git branch --show-current)) + export WOLFSSL_TAG=$(cd ${REPO_ROOT}/wolfssl-source && + (git describe --tags 2>/dev/null || git branch --show-current)) +else + echo "[FAIL] OpenSSL or wolfSSL source directories not found" + echo "Please run build-wolfprovider.sh first" + exit 1 +fi + +# Use the current version tags for testing +export USE_CUR_TAG=1 + +# Source OpenSSL utilities and initialize OpenSSL +source "${UTILS_DIR}/utils-openssl.sh" +init_openssl + +echo "=== Running wolfProvider Command-Line Tests ===" +echo "Using OpenSSL version: ${OPENSSL_TAG}" +echo "Using wolfSSL version: ${WOLFSSL_TAG}" + +# Run the hash comparison test +echo -e "\n=== Running Hash Comparison Test ===" +"${REPO_ROOT}/scripts/cmd_test/hash-cmd-test.sh" +HASH_RESULT=$? + +# Run the AES comparison test +echo -e "\n=== Running AES Comparison Test ===" +"${REPO_ROOT}/scripts/cmd_test/aes-cmd-test.sh" +AES_RESULT=$? + +# Run the RSA key generation test +echo -e "\n=== Running RSA Key Generation Test ===" +"${REPO_ROOT}/scripts/cmd_test/rsa-cmd-test.sh" +RSA_RESULT=$? + +# Run the ECC key generation test +echo -e "\n=== Running ECC Key Generation Test ===" +"${REPO_ROOT}/scripts/cmd_test/ecc-cmd-test.sh" +ECC_RESULT=$? + +# Check results +if [ $HASH_RESULT -eq 0 ] && [ $AES_RESULT -eq 0 ] && [ $RSA_RESULT -eq 0 ] && [ $ECC_RESULT -eq 0 ]; then + echo -e "\n=== All Command-Line Tests Passed ===" + exit 0 +else + echo -e "\n=== Command-Line Tests Failed ===" + echo "Hash Test Result: $HASH_RESULT (0=success)" + echo "AES Test Result: $AES_RESULT (0=success)" + echo "RSA Test Result: $RSA_RESULT (0=success)" + echo "ECC Test Result: $ECC_RESULT (0=success)" + exit 1 +fi diff --git a/scripts/cmd_test/ecc-cmd-test.sh b/scripts/cmd_test/ecc-cmd-test.sh new file mode 100755 index 00000000..acb79b10 --- /dev/null +++ b/scripts/cmd_test/ecc-cmd-test.sh @@ -0,0 +1,286 @@ +#!/bin/bash +# ecc-cmd-test.sh +# ECC key generation test for wolfProvider +# +# Copyright (C) 2006-2024 wolfSSL Inc. +# +# This file is part of wolfProvider. +# +# wolfProvider is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# wolfProvider is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + +# Set up environment +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +REPO_ROOT="$( cd "${SCRIPT_DIR}/../.." &> /dev/null && pwd )" +UTILS_DIR="${REPO_ROOT}/scripts" +export LOG_FILE="${SCRIPT_DIR}/ecc-test.log" +touch "$LOG_FILE" + +# Source wolfProvider utilities +source "${UTILS_DIR}/utils-general.sh" +source "${UTILS_DIR}/utils-openssl.sh" +source "${UTILS_DIR}/utils-wolfssl.sh" +source "${UTILS_DIR}/utils-wolfprovider.sh" + +# Initialize the environment +init_wolfprov + +# Fail flag +FAIL=0 + +# Verify wolfProvider is properly loaded +echo -e "\nVerifying wolfProvider configuration:" +if ! $OPENSSL_BIN list -providers | grep -q "libwolfprov"; then + echo "[FAIL] wolfProvider not found in OpenSSL providers!" + echo "Current provider list:" + $OPENSSL_BIN list -providers + exit 1 +fi +echo "[PASS] wolfProvider is properly configured" + +# Print environment for verification +echo "Environment variables:" +echo "OPENSSL_MODULES: ${OPENSSL_MODULES}" +echo "LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}" +echo "OPENSSL_BIN: ${OPENSSL_BIN}" + +# Create test directories +mkdir -p ecc_outputs + +# Create test data for signing +echo "This is test data for ECC signing and verification." > ecc_outputs/test_data.txt + +# Array of ECC curves and providers to test +CURVES=("prime256v1" "secp384r1" "secp521r1") +PROVIDER_ARGS=("-provider-path $WOLFPROV_PATH -provider libwolfprov" "-provider default") + +# Function to use default provider only +use_default_provider() { + unset OPENSSL_MODULES + unset OPENSSL_CONF + echo "Switched to default provider" +} + +# Function to use wolf provider only +use_wolf_provider() { + export OPENSSL_MODULES=$WOLFPROV_PATH + export OPENSSL_CONF=${WOLFPROV_CONFIG} + echo "Switched to wolfProvider" +} + +echo "=== Running ECC Key Generation Tests ===" + +# Function to validate key +validate_key() { + local curve=$1 + local key_file=${2:-"ecc_outputs/ecc_${curve}.pem"} + local provider_args=$3 + echo -e "\n=== Validating ECC Key (${curve}) ===" + + # First check if file exists + if [ ! -f "$key_file" ]; then + echo "[FAIL] ECC key (${curve}) file does not exist" + FAIL=1 + return 1 + fi + + # Then check if file is empty (has size 0) + if [ ! -s "$key_file" ]; then + echo "[FAIL] ECC key (${curve}) file is empty" + FAIL=1 + return 1 + fi + echo "[PASS] ECC key file exists and has content" + + # Try to extract public key + local pub_key_file="ecc_outputs/ecc_${curve}_pub.pem" + if $OPENSSL_BIN pkey -in "$key_file" -pubout -out "$pub_key_file" \ + ${provider_args} -passin pass: >/dev/null; then + echo "[PASS] ECC Public key extraction successful" + else + echo "[FAIL] ECC Public key extraction failed" + FAIL=1 + return 1 + fi +} + +# Function to sign data with ECC +sign_ecc() { + local key_file=$1 + local data_file=$2 + local sig_file=$3 + local provider_args=$4 + + echo "Signing data with ECC..." + $OPENSSL_BIN pkeyutl -sign -inkey "$key_file" \ + ${provider_args} -passin pass: \ + -in "$data_file" \ + -out "$sig_file" + return $? +} + +# Function to verify ECC signature +verify_ecc() { + local pub_key_file=$1 + local data_file=$2 + local sig_file=$3 + local provider_args=$4 + + echo "Verifying ECC signature..." + $OPENSSL_BIN pkeyutl -verify -pubin -inkey "$pub_key_file" \ + ${provider_args} -passin pass: \ + -in "$data_file" \ + -sigfile "$sig_file" + return $? +} + +# Generic function to test sign/verify interoperability using pkeyutl +test_sign_verify_pkeyutl() { + local curve=$1 + local provider_args=$2 + + # Print the provider args + if [ "$provider_args" = "-provider default" ]; then + provider_name="default" + else + provider_name="wolfProvider" + fi + + local key_file="ecc_outputs/ecc_${curve}.pem" + local pub_key_file="ecc_outputs/ecc_${curve}_pub.pem" + local data_file="ecc_outputs/test_data.txt" + + echo -e "\n=== Testing ECC (${curve}) Sign/Verify with pkeyutl Using ${provider_name} ===" + + # Test 1: Sign and verify with OpenSSL default + use_default_provider + echo "Test 1: Sign and verify with OpenSSL default" + local default_sig_file="ecc_outputs/ecc_${curve}_default_sig.bin" + if sign_ecc "$key_file" "$data_file" "$default_sig_file" "$provider_args"; then + echo "[PASS] Signing with OpenSSL default successful" + if verify_ecc "$pub_key_file" "$data_file" "$default_sig_file" "$provider_args"; then + echo "[PASS] Default provider verify successful" + else + echo "[FAIL] Default provider verify failed" + FAIL=1 + fi + else + echo "[FAIL] Default provider signing failed" + FAIL=1 + fi + + # Test 2: Sign and verify with wolfProvider + use_wolf_provider + echo "Test 2: Sign and verify with wolfProvider" + local wolf_sig_file="ecc_outputs/ecc_${curve}_wolf_sig.bin" + if sign_ecc "$key_file" "$data_file" "$wolf_sig_file" "$provider_args"; then + echo "[PASS] Signing with wolfProvider successful" + if verify_ecc "$pub_key_file" "$data_file" "$wolf_sig_file" "$provider_args"; then + echo "[PASS] wolfProvider sign/verify successful" + else + echo "[FAIL] wolfProvider verify failed" + FAIL=1 + fi + else + echo "[FAIL] wolfProvider signing failed" + FAIL=1 + fi + + # Test 3: Cross-provider verification (default sign, wolf verify) + if [ $FAIL -eq 0 ]; then # only verify if previous tests passed + use_wolf_provider + echo "Test 3: Cross-provider verification (default sign, wolf verify)" + if verify_ecc "$pub_key_file" "$data_file" "$default_sig_file" "$provider_args"; then + echo "[PASS] wolfProvider can verify OpenSSL default signature" + else + echo "[FAIL] wolfProvider cannot verify OpenSSL default signature" + FAIL=1 + fi + + # Test 4: Cross-provider verification (wolf sign, default verify) + use_default_provider + echo "Test 4: Cross-provider verification (wolf sign, default verify)" + if verify_ecc "$pub_key_file" "$data_file" "$wolf_sig_file" "$provider_args"; then + echo "[PASS] OpenSSL default can verify wolfProvider signature" + else + echo "[FAIL] OpenSSL default cannot verify wolfProvider signature" + FAIL=1 + fi + else + echo "[INFO] Cannot verify cross-provider signatures - no key available" + fi +} + +# Function to generate and test ECC keys +generate_and_test_key() { + local curve=$1 + local provider_args=$2 + local output_file="ecc_outputs/ecc_${curve}.pem" + + echo -e "\n=== Testing ECC Key Generation (${curve}) with provider default ===" + echo "Generating ECC key (${curve})..." + + if $OPENSSL_BIN ecparam -name $curve -genkey \ + ${provider_args} \ + -out "$output_file" 2>/dev/null; then + echo "[PASS] ECC key generation successful" + else + echo "[FAIL] ECC key generation failed" + FAIL=1 + fi + + # Verify the key was generated + if [ -s "$output_file" ]; then + echo "[PASS] ECC key generation successful" + else + echo "[FAIL] ECC key generation failed" + FAIL=1 + fi + + # Validate key + validate_key "$curve" "$output_file" "$provider_args" + + # Try to use the key with provider default + echo -e "\n=== Testing ECC Key (${curve}) with provider default ===" + echo "Checking if provider default can use the key..." + + # Try to use the key with wolfProvider (just check if it loads) + if $OPENSSL_BIN pkey -in "$output_file" -check \ + ${provider_args} -passin pass: >/dev/null; then + echo "[PASS] provider default can use ECC key (${curve})" + else + echo "[FAIL] provider default cannot use ECC key (${curve})" + FAIL=1 + fi +} + +# Test key generation for each curve and provider +for curve in "${CURVES[@]}"; do + # Generate with default provider + test_provider="-provider default" + generate_and_test_key "$curve" "$test_provider" + + # Test sign/verify interoperability with appropriate function + for test_provider in "${PROVIDER_ARGS[@]}"; do + test_sign_verify_pkeyutl "$curve" "$test_provider" + done +done + +if [ $FAIL -eq 0 ]; then + echo -e "\n=== All ECC key generation tests completed successfully ===" + exit 0 +else + echo -e "\n=== ECC key generation tests completed with failures ===" + exit 1 +fi diff --git a/scripts/cmd_test/hash-cmd-test.sh b/scripts/cmd_test/hash-cmd-test.sh new file mode 100755 index 00000000..1aa15e07 --- /dev/null +++ b/scripts/cmd_test/hash-cmd-test.sh @@ -0,0 +1,117 @@ +#!/bin/bash + +# Set up environment +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +REPO_ROOT="$( cd "${SCRIPT_DIR}/../.." &> /dev/null && pwd )" +UTILS_DIR="${REPO_ROOT}/scripts" +export LOG_FILE="${SCRIPT_DIR}/hash-test.log" +touch "$LOG_FILE" + +# Source wolfProvider utilities +source "${UTILS_DIR}/utils-general.sh" +source "${UTILS_DIR}/utils-openssl.sh" +source "${UTILS_DIR}/utils-wolfssl.sh" +source "${UTILS_DIR}/utils-wolfprovider.sh" + +# Initialize the environment +init_wolfprov + +# Fail flag +FAIL=0 + +# Verify wolfProvider is properly loaded +echo -e "\nVerifying wolfProvider configuration:" +if ! $OPENSSL_BIN list -providers | grep -q "wolf"; then + echo "[FAIL] wolfProvider not found in OpenSSL providers!" + echo "Current provider list:" + $OPENSSL_BIN list -providers + FAIL=1 +else + echo "[PASS] wolfProvider is properly configured" +fi + +# Print environment for verification +echo "Environment variables:" +echo "OPENSSL_MODULES: ${OPENSSL_MODULES}" +echo "LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}" +echo "OPENSSL_BIN: ${OPENSSL_BIN}" + +# Create test data and output directories +mkdir -p hash_outputs +echo "This is test data for hash algorithm testing." > test.txt + +# Function to run hash test with specified provider options +run_hash_test() { + local algo="$1" + local provider_opts="$2" + local output_file="$3" + + # Run the hash algorithm with specified provider options + if ! $OPENSSL_BIN dgst -$algo $provider_opts -out "$output_file" test.txt; then + echo "[FAIL] Hash generation failed for ${algo}" + FAIL=1 + fi + + # Check if output file has content + if [ ! -s "$output_file" ]; then + echo "[FAIL] No hash output generated for ${algo}" + FAIL=1 + fi + + # Print the hash for verification if file exists and has content + if [ -s "$output_file" ]; then + cat "$output_file" + fi +} + +# Function to compare hash outputs +compare_hashes() { + local algo="$1" + local openssl_file="hash_outputs/openssl_${algo}.txt" + local wolf_file="hash_outputs/wolf_${algo}.txt" + + # Check if both files exist and have content + if [ ! -s "$openssl_file" ] || [ ! -s "$wolf_file" ]; then + echo "[INFO] Cannot compare hashes - one or both hash files are empty" + FAIL=1 + else + echo -e "\nComparing ${algo} hashes:" + echo "OpenSSL: $(cat $openssl_file)" + echo "Wolf: $(cat $wolf_file)" + + if cmp -s "$openssl_file" "$wolf_file"; then + echo "[PASS] ${algo} hashes match" + else + echo "[FAIL] ${algo} hashes don't match" + FAIL=1 + fi + fi +} + +# Array of hash algorithms to test +HASH_ALGOS=("sha1" "sha224" "sha256" "sha384" "sha512") + +echo "=== Running Hash Algorithm Comparisons ===" + +# Run tests for each hash algorithm +for algo in "${HASH_ALGOS[@]}"; do + echo -e "\n=== Testing ${algo^^} ===" + + # Test with OpenSSL default provider + run_hash_test $algo "-provider default" "hash_outputs/openssl_${algo}.txt" + + # Test with wolfProvider + run_hash_test $algo "-provider-path $WOLFPROV_PATH -provider libwolfprov" "hash_outputs/wolf_${algo}.txt" + + # Compare results + compare_hashes $algo +done + +# Modify end of script +if [ $FAIL -eq 0 ]; then + echo -e "\n=== All hash tests completed successfully ===" + exit 0 +else + echo -e "\n=== Hash tests completed with failures ===" + exit 1 +fi diff --git a/scripts/cmd_test/rsa-cmd-test.sh b/scripts/cmd_test/rsa-cmd-test.sh new file mode 100755 index 00000000..e8948dc5 --- /dev/null +++ b/scripts/cmd_test/rsa-cmd-test.sh @@ -0,0 +1,356 @@ +#!/bin/bash +# rsa-cmd-test.sh +# RSA and RSA-PSS key generation test for wolfProvider +# +# Copyright (C) 2006-2024 wolfSSL Inc. +# +# This file is part of wolfProvider. +# +# wolfProvider is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# wolfProvider is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + +# Set up environment +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +REPO_ROOT="$( cd "${SCRIPT_DIR}/../.." &> /dev/null && pwd )" +UTILS_DIR="${REPO_ROOT}/scripts" +export LOG_FILE="${SCRIPT_DIR}/rsa-test.log" +touch "$LOG_FILE" + +# Source wolfProvider utilities +source "${UTILS_DIR}/utils-general.sh" +source "${UTILS_DIR}/utils-openssl.sh" +source "${UTILS_DIR}/utils-wolfssl.sh" +source "${UTILS_DIR}/utils-wolfprovider.sh" + +# Initialize the environment +init_wolfprov + +# Fail flag +FAIL=0 + +# Verify wolfProvider is properly loaded +echo -e "\nVerifying wolfProvider configuration:" +if ! $OPENSSL_BIN list -providers | grep -q "libwolfprov"; then + echo "[FAIL] wolfProvider not found in OpenSSL providers!" + echo "Current provider list:" + $OPENSSL_BIN list -providers + exit 1 +fi +echo "[PASS] wolfProvider is properly configured" + +# Print environment for verification +echo "Environment variables:" +echo "OPENSSL_MODULES: ${OPENSSL_MODULES}" +echo "LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}" +echo "OPENSSL_BIN: ${OPENSSL_BIN}" + +# Create test directories +mkdir -p rsa_outputs + +# Create test data for signing +echo "This is test data for RSA signing and verification." > rsa_outputs/test_data.txt + +# Array of RSA key types, sizes, and providers to test +KEY_TYPES=("RSA" "RSA-PSS") +KEY_SIZES=("2048" "3072" "4096") +PROVIDER_ARGS=("-provider-path $WOLFPROV_PATH -provider libwolfprov" "-provider default") + +# Function to use default provider only +use_default_provider() { + unset OPENSSL_MODULES + unset OPENSSL_CONF + echo "Switched to default provider" +} + +# Function to use wolf provider only +use_wolf_provider() { + export OPENSSL_MODULES=$WOLFPROV_PATH + export OPENSSL_CONF=${WOLFPROV_CONFIG} + echo "Switched to wolfProvider" +} + +echo "=== Running RSA Key Generation Tests ===" + +# Function to validate key +validate_key() { + local key_type=$1 + local key_size=$2 + local key_file=${3:-"rsa_outputs/${key_type}_${key_size}.pem"} + local provider_args=$4 + echo -e "\n=== Validating ${key_type} Key (${key_size}) ===" + + # First check if file exists + if [ ! -f "$key_file" ]; then + echo "[FAIL] ${key_type} key (${key_size}) file does not exist" + FAIL=1 + fi + + # Then check if file is empty (has size 0) + if [ ! -s "$key_file" ]; then + echo "[FAIL] ${key_type} key (${key_size}) file is empty" + FAIL=1 + fi + echo "[PASS] ${key_type} key file exists and has content" + + # Try to extract public key + local pub_key_file="rsa_outputs/${key_type}_${key_size}_pub.pem" + if $OPENSSL_BIN pkey -in "$key_file" -pubout -out "$pub_key_file" \ + ${provider_args} -passin pass: >/dev/null; then + echo "[PASS] ${key_type} Public key extraction successful" + else + echo "[FAIL] ${key_type} Public key extraction failed" + FAIL=1 + fi +} + +# Function to sign data with RSA-PSS +sign_rsa_pss() { + local key_file=$1 + local data_file=$2 + local sig_file=$3 + local provider_args=$4 + + echo "Signing data with RSA-PSS..." + $OPENSSL_BIN pkeyutl -sign -inkey "$key_file" \ + ${provider_args} -provider default -passin pass: \ + -rawin -digest sha256 \ + -pkeyopt rsa_padding_mode:pss \ + -pkeyopt rsa_pss_saltlen:-1 \ + -pkeyopt rsa_mgf1_md:sha256 \ + -in "$data_file" \ + -out "$sig_file" + return $? +} + +# Function to verify RSA-PSS signature +verify_rsa_pss() { + local pub_key_file=$1 + local data_file=$2 + local sig_file=$3 + local provider_args=$4 + + echo "Verifying RSA-PSS signature..." + $OPENSSL_BIN pkeyutl -verify -pubin -inkey "$pub_key_file" \ + ${provider_args} -provider default -passin pass: \ + -rawin -digest sha256 \ + -pkeyopt rsa_padding_mode:pss \ + -pkeyopt rsa_pss_saltlen:-1 \ + -pkeyopt rsa_mgf1_md:sha256 \ + -in "$data_file" \ + -sigfile "$sig_file" + return $? +} + +# Function to sign data with standard RSA +sign_rsa() { + local key_file=$1 + local data_file=$2 + local sig_file=$3 + local provider_args=$4 + + echo "Signing data with standard RSA..." + $OPENSSL_BIN pkeyutl -sign -inkey "$key_file" \ + ${provider_args} -passin pass: \ + -in "$data_file" \ + -out "$sig_file" + return $? +} + +# Function to verify standard RSA signature +verify_rsa() { + local pub_key_file=$1 + local data_file=$2 + local sig_file=$3 + local provider_args=$4 + + echo "Verifying standard RSA signature..." + $OPENSSL_BIN pkeyutl -verify -pubin -inkey "$pub_key_file" \ + ${provider_args} -passin pass: \ + -in "$data_file" \ + -sigfile "$sig_file" + return $? +} + +# Generic function to test sign/verify interoperability using pkeyutl +test_sign_verify_pkeyutl() { + local key_type=$1 + local key_size=$2 + local provider_args=$3 + local sign_func=$4 + local verify_func=$5 + + # Print the provider args + if [ "$provider_args" = "-provider default" ]; then + provider_name="default" + else + provider_name="wolfProvider" + fi + + # Handle different key naming conventions + local key_prefix="${key_type}" + if [ "$key_type" = "RSA" ]; then + key_prefix="RSA" + fi + + local key_file="rsa_outputs/${key_prefix}_${key_size}.pem" + local pub_key_file="rsa_outputs/${key_prefix}_${key_size}_pub.pem" + local data_file="rsa_outputs/test_data.txt" + + echo -e "\n=== Testing ${key_type} (${key_size}) Sign/Verify with pkeyutl Using ${provider_name} ===" + + # Test 1: Sign and verify with OpenSSL default + use_default_provider + echo "Test 1: Sign and verify with OpenSSL default (${key_type})" + local default_sig_file="rsa_outputs/${key_prefix}_${key_size}_default_sig.bin" + if $sign_func "$key_file" "$data_file" "$default_sig_file" "$provider_args"; then + echo "[PASS] Signing with OpenSSL default successful" + if $verify_func "$pub_key_file" "$data_file" "$default_sig_file" "$provider_args"; then + echo "[PASS] Default provider verify successful" + else + echo "[FAIL] Default provider verify failed" + FAIL=1 + fi + else + echo "[FAIL] Default provider signing failed" + FAIL=1 + fi + + # Test 2: Sign and verify with wolfProvider + use_wolf_provider + echo "Test 2: Sign and verify with wolfProvider (${key_type})" + local wolf_sig_file="rsa_outputs/${key_prefix}_${key_size}_wolf_sig.bin" + if $sign_func "$key_file" "$data_file" "$wolf_sig_file" "$provider_args"; then + echo "[PASS] Signing with wolfProvider successful" + if $verify_func "$pub_key_file" "$data_file" "$wolf_sig_file" "$provider_args"; then + echo "[PASS] wolfProvider sign/verify successful" + else + echo "[FAIL] wolfProvider verify failed" + FAIL=1 + fi + else + echo "[FAIL] wolfProvider signing failed" + FAIL=1 + fi + + # Test 3: Cross-provider verification (default sign, wolf verify) + if [ $FAIL -eq 0 ]; then # only verify if previous tests passed + use_wolf_provider + echo "Test 3: Cross-provider verification (default sign, wolf verify)" + if $verify_func "$pub_key_file" "$data_file" "$default_sig_file" "$provider_args"; then + echo "[PASS] wolfProvider can verify OpenSSL default signature" + else + echo "[FAIL] wolfProvider cannot verify OpenSSL default signature" + FAIL=1 + fi + + # Test 4: Cross-provider verification (wolf sign, default verify) + use_default_provider + echo "Test 4: Cross-provider verification (wolf sign, default verify)" + if $verify_func "$pub_key_file" "$data_file" "$wolf_sig_file" "$provider_args"; then + echo "[PASS] OpenSSL default can verify wolfProvider signature" + else + echo "[FAIL] OpenSSL default cannot verify wolfProvider signature" + FAIL=1 + fi + else + echo "[INFO] Cannot verify cross-provider signatures no key available" + fi +} + +# Function to generate and test RSA keys +generate_and_test_key() { + local key_type=$1 + local key_size=$2 + local provider_args=$3 + local output_file="rsa_outputs/${key_type}_${key_size}.pem" + + echo -e "\n=== Testing ${key_type} Key Generation (${key_size}) with provider default ===" + echo "Generating ${key_type} key (${key_size})..." + if [ "$key_type" = "RSA-PSS" ]; then + # For RSA-PSS, specify all parameters + if $OPENSSL_BIN genpkey -algorithm RSA-PSS \ + ${provider_args} \ + -pkeyopt rsa_keygen_bits:${key_size} \ + -pkeyopt rsa_pss_keygen_md:sha256 \ + -pkeyopt rsa_pss_keygen_mgf1_md:sha256 \ + -pkeyopt rsa_pss_keygen_saltlen:-1 \ + -out "$output_file" 2>/dev/null; then + echo "[PASS] RSA-PSS key generation successful" + else + echo "[FAIL] RSA-PSS key generation failed" + FAIL=1 + fi + else + # Regular RSA key generation + if $OPENSSL_BIN genpkey -algorithm RSA \ + ${provider_args} \ + -pkeyopt rsa_keygen_bits:${key_size} \ + -out "$output_file" 2>/dev/null; then + echo "[PASS] RSA key generation successful" + else + echo "[FAIL] RSA key generation failed" + FAIL=1 + fi + fi + + # Verify the key was generated + if [ -s "$output_file" ]; then + echo "[PASS] ${key_type} key (${key_size}) generation successful" + else + echo "[FAIL] ${key_type} key (${key_size}) generation failed" + FAIL=1 + fi + + # Validate key + validate_key "$key_type" "$key_size" "$output_file" "$provider_args" + + # Try to use the key with provider default + echo -e "\n=== Testing ${key_type} Key (${key_size}) with provider default ===" + echo "Checking if provider default can use the key..." + + # Try to use the key with wolfProvider (just check if it loads) + if $OPENSSL_BIN pkey -in "$output_file" -check \ + ${provider_args} -passin pass: >/dev/null; then + echo "[PASS] provider default can use ${key_type} key (${key_size})" + else + echo "[FAIL] provider default cannot use ${key_type} key (${key_size})" + FAIL=1 + fi +} + +# Test key generation for each type, size, and provider +for key_type in "${KEY_TYPES[@]}"; do + for key_size in "${KEY_SIZES[@]}"; do + # Generate with default provider + test_provider="-provider default" + generate_and_test_key "$key_type" "$key_size" "$test_provider" + + # Test sign/verify interoperability with appropriate function + for test_provider in "${PROVIDER_ARGS[@]}"; do + if [ "$key_type" = "RSA-PSS" ]; then + test_sign_verify_pkeyutl "$key_type" "$key_size" "$test_provider" sign_rsa_pss verify_rsa_pss + else + test_sign_verify_pkeyutl "$key_type" "$key_size" "$test_provider" sign_rsa verify_rsa + fi + done + done +done + +if [ $FAIL -eq 0 ]; then + echo -e "\n=== All RSA key generation tests completed successfully ===" + exit 0 +else + echo -e "\n=== RSA key generation tests completed with failures ===" + exit 1 +fi diff --git a/scripts/utils-openssl.sh b/scripts/utils-openssl.sh index 62284f42..14069139 100755 --- a/scripts/utils-openssl.sh +++ b/scripts/utils-openssl.sh @@ -32,9 +32,10 @@ OPENSSL_INSTALL_DIR=${SCRIPT_DIR}/../openssl-install NUMCPU=${NUMCPU:-8} WOLFPROV_DEBUG=${WOLFPROV_DEBUG:-0} +USE_CUR_TAG=${USE_CUR_TAG:-0} clone_openssl() { - if [ -d ${OPENSSL_SOURCE_DIR} ]; then + if [ -d ${OPENSSL_SOURCE_DIR} ] && [ "$USE_CUR_TAG" != "1" ]; then OPENSSL_TAG_CUR=$(cd ${OPENSSL_SOURCE_DIR} && (git describe --tags 2>/dev/null || git branch --show-current)) if [ "${OPENSSL_TAG_CUR}" != "${OPENSSL_TAG}" ]; then # force a rebuild printf "Version inconsistency. Please fix ${OPENSSL_SOURCE_DIR} (expected: ${OPENSSL_TAG}, got: ${OPENSSL_TAG_CUR})\n" @@ -44,16 +45,17 @@ clone_openssl() { fi if [ ! -d ${OPENSSL_SOURCE_DIR} ]; then - printf "\tClone OpenSSL ${OPENSSL_TAG} ... " - if [ "$WOLFPROV_DEBUG" = "1" ]; then - git clone -b ${OPENSSL_TAG} ${OPENSSL_GIT} \ - ${OPENSSL_SOURCE_DIR} >>$LOG_FILE 2>&1 - RET=$? - else - git clone --depth=1 -b ${OPENSSL_TAG} ${OPENSSL_GIT} \ - ${OPENSSL_SOURCE_DIR} >>$LOG_FILE 2>&1 - RET=$? - fi + CLONE_TAG=${USE_CUR_TAG:+${OPENSSL_TAG_CUR}} + CLONE_TAG=${CLONE_TAG:-${OPENSSL_TAG}} + + printf "\tClone OpenSSL ${CLONE_TAG} ... " + + DEPTH_ARG=${WOLFPROV_DEBUG:+""} + DEPTH_ARG=${DEPTH_ARG:---depth=1} + + git clone ${DEPTH_ARG} -b ${CLONE_TAG} ${OPENSSL_GIT} ${OPENSSL_SOURCE_DIR} >>$LOG_FILE 2>&1 + RET=$? + if [ $RET != 0 ]; then printf "ERROR.\n" do_cleanup diff --git a/scripts/utils-wolfssl.sh b/scripts/utils-wolfssl.sh index f433e485..f4161815 100755 --- a/scripts/utils-wolfssl.sh +++ b/scripts/utils-wolfssl.sh @@ -30,6 +30,7 @@ WOLFSSL_CONFIG_OPTS=${WOLFSSL_CONFIG_OPTS:-'--enable-all-crypto --with-eccminsz= WOLFSSL_CONFIG_CFLAGS=${WOLFSSL_CONFIG_CFLAGS:-"-I${OPENSSL_INSTALL_DIR}/include -DWC_RSA_NO_PADDING -DWOLFSSL_PUBLIC_MP -DHAVE_PUBLIC_FFDHE -DHAVE_FFDHE_6144 -DHAVE_FFDHE_8192 -DWOLFSSL_PSS_LONG_SALT -DWOLFSSL_PSS_SALT_LEN_DISCOVER -DRSA_MIN_SIZE=1024"} WOLFPROV_DEBUG=${WOLFPROV_DEBUG:-0} +USE_CUR_TAG=${USE_CUR_TAG:-0} # Depends on OPENSSL_INSTALL_DIR clone_wolfssl() { @@ -38,7 +39,7 @@ clone_wolfssl() { mkdir ${WOLFSSL_SOURCE_DIR} cp -pr ${WOLFSSL_FIPS_BUNDLE}/* ${WOLFSSL_SOURCE_DIR}/ else - if [ -d ${WOLFSSL_SOURCE_DIR} ]; then + if [ -d ${WOLFSSL_SOURCE_DIR} ] && [ "$USE_CUR_TAG" != "1" ]; then WOLFSSL_TAG_CUR=$(cd ${WOLFSSL_SOURCE_DIR} && (git describe --tags 2>/dev/null || git branch --show-current)) if [ "${WOLFSSL_TAG_CUR}" != "${WOLFSSL_TAG}" ]; then # force a rebuild printf "Version inconsistency. Please fix ${WOLFSSL_SOURCE_DIR} (expected: ${WOLFSSL_TAG}, got: ${WOLFSSL_TAG_CUR})\n" @@ -48,16 +49,17 @@ clone_wolfssl() { fi if [ ! -d ${WOLFSSL_SOURCE_DIR} ]; then - printf "\tClone wolfSSL ${WOLFSSL_TAG} ... " - if [ "$WOLFPROV_DEBUG" = "1" ]; then - git clone -b ${WOLFSSL_TAG} ${WOLFSSL_GIT} \ - ${WOLFSSL_SOURCE_DIR} >>$LOG_FILE 2>&1 - RET=$? - else - git clone --depth=1 -b ${WOLFSSL_TAG} ${WOLFSSL_GIT} \ - ${WOLFSSL_SOURCE_DIR} >>$LOG_FILE 2>&1 - RET=$? - fi + CLONE_TAG=${USE_CUR_TAG:+${WOLFSSL_TAG_CUR}} + CLONE_TAG=${CLONE_TAG:-${WOLFSSL_TAG}} + + printf "\tClone wolfSSL ${CLONE_TAG} ... " + + DEPTH_ARG=${WOLFPROV_DEBUG:+""} + DEPTH_ARG=${DEPTH_ARG:---depth=1} + + git clone ${DEPTH_ARG} -b ${CLONE_TAG} ${WOLFSSL_GIT} ${WOLFSSL_SOURCE_DIR} >>$LOG_FILE 2>&1 + RET=$? + if [ $RET != 0 ]; then printf "ERROR cloning\n" do_cleanup