1# Copyright (c) 2022, Google Inc. 2# 3# Permission to use, copy, modify, and/or distribute this software for any 4# purpose with or without fee is hereby granted, provided that the above 5# copyright notice and this permission notice appear in all copies. 6# 7# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 10# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 12# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 13# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 15# This script runs test_fips repeatedly with different FIPS tests broken. It is 16# intended to be observed to demonstrate that the various tests are working and 17# thus pauses for a keystroke between tests. 18# 19# Runs in either device mode (on an attached Android device) or in a locally built 20# BoringSSL checkout. 21# 22# On Android static binaries are not built using FIPS mode, so in device mode each 23# test makes changes to libcrypto.so rather than the test binary, test_fips. 24 25set -e 26 27die () { 28 echo "ERROR: $@" 29 exit 1 30} 31 32usage() { 33 echo "USAGE: $0 [local|device]" 34 exit 1 35} 36 37inferred_mode() { 38 # Try and infer local or device mode based on makefiles and artifacts. 39 if [ -f Android.bp -o -f external/boringssl/Android.bp ]; then 40 echo device 41 elif [ -f CMakeLists.txt -a -d build/crypto -a -d build/ssl ]; then 42 echo local 43 else 44 echo "Unable to infer mode, please specify on the command line." 45 usage 46 fi 47} 48 49MODE=`inferred_mode` 50# Prefer mode from command line if present. 51while [ "$1" ]; do 52 case "$1" in 53 local|device) 54 MODE=$1 55 ;; 56 57 "32") 58 TEST32BIT="true" 59 ;; 60 61 *) 62 usage 63 ;; 64 esac 65 shift 66done 67 68check_directory() { 69 test -d "$1" || die "Directory $1 not found." 70} 71 72check_file() { 73 test -f "$1" || die "File $1 not found." 74} 75 76run_test_locally() { 77 eval "$1" || true 78} 79 80run_test_on_device() { 81 EXECFILE="$1" 82 LIBRARY="$2" 83 adb shell rm -rf "$DEVICE_TMP" 84 adb shell mkdir -p "$DEVICE_TMP" 85 adb push "$EXECFILE" "$DEVICE_TMP" > /dev/null 86 EXECPATH=$(basename "$EXECFILE") 87 adb push "$LIBRARY" "$DEVICE_TMP" > /dev/null 88 adb shell "LD_LIBRARY_PATH=$DEVICE_TMP" "$DEVICE_TMP/$EXECPATH" || true 89} 90 91device_integrity_break_test() { 92 go run "$BORINGSSL/util/fipstools/break-hash.go" "$LIBCRYPTO_BIN" ./libcrypto.so 93 $RUN "$TEST_FIPS_BIN" ./libcrypto.so 94 rm ./libcrypto.so 95} 96 97local_integrity_break_test() { 98 go run $BORINGSSL/util/fipstools/break-hash.go "$TEST_FIPS_BIN" ./break-bin 99 chmod u+x ./break-bin 100 $RUN ./break-bin 101 rm ./break-bin 102} 103 104local_runtime_break_test() { 105 BORINGSSL_FIPS_BREAK_TEST=$1 "$RUN" "$TEST_FIPS_BREAK_BIN" 106} 107 108# TODO(prb): make break-hash and break-kat take similar arguments to save having 109# separate functions for each. 110device_kat_break_test() { 111 KAT="$1" 112 go run "$BORINGSSL/util/fipstools/break-kat.go" "$LIBCRYPTO_BREAK_BIN" "$KAT" > ./libcrypto.so 113 $RUN "$TEST_FIPS_BIN" ./libcrypto.so 114 rm ./libcrypto.so 115} 116 117local_kat_break_test() { 118 KAT="$1" 119 go run "$BORINGSSL/util/fipstools/break-kat.go" "$TEST_FIPS_BREAK_BIN" "$KAT" > ./break-bin 120 chmod u+x ./break-bin 121 $RUN ./break-bin 122 rm ./break-bin 123} 124 125pause () { 126 echo -n "Press <Enter> " 127 read 128} 129 130if [ "$MODE" = "local" ]; then 131 TEST_FIPS_BIN=${TEST_FIPS_BIN:-build/util/fipstools/test_fips} 132 TEST_FIPS_BREAK_BIN=${TEST_FIPS_BREAK_BIN:-./test_fips_break} 133 check_file "$TEST_FIPS_BIN" 134 check_file "$TEST_FIPS_BREAK_BIN" 135 136 BORINGSSL=. 137 RUN=run_test_locally 138 BREAK_TEST=local_break_test 139 INTEGRITY_BREAK_TEST=local_integrity_break_test 140 KAT_BREAK_TEST=local_kat_break_test 141 RUNTIME_BREAK_TEST=local_runtime_break_test 142 if [ ! -f "$TEST_FIPS_BIN" ]; then 143 echo "$TEST_FIPS_BIN is missing. Run this script from the top level of a" 144 echo "BoringSSL checkout and ensure that BoringSSL has been built in" 145 echo "build/ with -DFIPS_BREAK_TEST=TESTS passed to CMake." 146 exit 1 147 fi 148else # Device mode 149 test "$ANDROID_BUILD_TOP" || die "'lunch aosp_arm64-eng' first" 150 check_directory "$ANDROID_PRODUCT_OUT" 151 152 if [ "$TEST32BIT" ]; then 153 TEST_FIPS_BIN="$ANDROID_PRODUCT_OUT/system/bin/test_fips32" 154 LIBCRYPTO_BIN="$ANDROID_PRODUCT_OUT/system/lib/libcrypto.so" 155 LIBCRYPTO_BREAK_BIN="$ANDROID_PRODUCT_OUT/system/lib/libcrypto_for_testing.so" 156 else 157 TEST_FIPS_BIN="$ANDROID_PRODUCT_OUT/system/bin/test_fips" 158 LIBCRYPTO_BIN="$ANDROID_PRODUCT_OUT/system/lib64/libcrypto.so" 159 LIBCRYPTO_BREAK_BIN="$ANDROID_PRODUCT_OUT/system/lib64/libcrypto_for_testing.so" 160 fi 161 check_file "$TEST_FIPS_BIN" 162 check_file "$LIBCRYPTO_BIN" 163 check_file "$LIBCRYPTO_BREAK_BIN" 164 165 test "$ANDROID_SERIAL" || die "ANDROID_SERIAL not set" 166 DEVICE_TMP=/data/local/tmp 167 168 BORINGSSL="$ANDROID_BUILD_TOP/external/boringssl/src" 169 RUN=run_test_on_device 170 INTEGRITY_BREAK_TEST=device_integrity_break_test 171 KAT_BREAK_TEST=device_kat_break_test 172fi 173 174 175KATS=$(go run "$BORINGSSL/util/fipstools/break-kat.go" --list-tests) 176 177echo -e '\033[1mNormal output\033[0m' 178$RUN "$TEST_FIPS_BIN" "$LIBCRYPTO_BIN" 179pause 180 181echo 182echo -e '\033[1mIntegrity test failure\033[0m' 183$INTEGRITY_BREAK_TEST 184pause 185 186for kat in $KATS; do 187 echo 188 echo -e "\033[1mKAT failure ${kat}\033[0m" 189 $KAT_BREAK_TEST $kat 190 pause 191done 192 193if [ "$MODE" = "local" ]; then 194 # TODO(prb): add support for Android devices. 195 for runtime_test in ECDSA_PWCT RSA_PWCT CRNG; do 196 echo 197 echo -e "\033[1m${runtime_test} failure\033[0m" 198 $RUNTIME_BREAK_TEST ${runtime_test} 199 pause 200 done 201fi 202