break-tests.sh: break run-time tests and use two test_fips binaries.

(This change breaks running on Android. But it's close to what we used
for non-Android FIPS testing so is useful to have on the record.)

This change adds testing of the run-time break tests: the pair-wise
consistency tests and the RNG test.

It also switches to using two test_fips binaries: an unmodified one for
showing a clean up and testing the integrity test, and a test_fips_break
which makes integrity test failures non-fatal (for KAT testing) and
which allows the run-time tests to be triggered.

Change-Id: Id2787723059cfb17cc2d22013ad66b985ef86701
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/53885
Reviewed-by: David Benjamin <davidben@google.com>
Auto-Submit: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/util/fipstools/break-tests.sh b/util/fipstools/break-tests.sh
index f9ae2e8..695b629 100644
--- a/util/fipstools/break-tests.sh
+++ b/util/fipstools/break-tests.sh
@@ -25,139 +25,147 @@
 set -e
 
 die () {
-    echo "ERROR: $@"
-    exit 1
+  echo "ERROR: $@"
+  exit 1
 }
 
 usage() {
-    echo "USAGE: $0 [local|device]"
-    exit 1
+  echo "USAGE: $0 [local|device]"
+  exit 1
 }
 
 inferred_mode() {
-    # Try and infer local or device mode based on makefiles and artifacts.
-    if [ -f Android.bp -o -f external/boringssl/Android.bp ]
-    then
-       echo device
-    elif [ -f CMakeLists.txt -a -d build/crypto -a -d build/ssl ]
-    then
-	echo local
-    else
-	echo "Unable to infer mode, please specify on the command line."
-	usage
-    fi
+  # Try and infer local or device mode based on makefiles and artifacts.
+  if [ -f Android.bp -o -f external/boringssl/Android.bp ]; then
+    echo device
+  elif [ -f CMakeLists.txt -a -d build/crypto -a -d build/ssl ]; then
+    echo local
+  else
+    echo "Unable to infer mode, please specify on the command line."
+    usage
+  fi
 }
 
 # Prefer mode from command line if present.
 case "$1" in
-    local|device)
-	MODE=$1
-	;;
+  local|device)
+    MODE=$1
+    ;;
 
-    "")
-	MODE=`inferred_mode`
-	;;
+  "")
+    MODE=`inferred_mode`
+    ;;
 
-    *)
-	usage
-	;;
+  *)
+    usage
+    ;;
 esac
 
 check_directory() {
-    test -d $1 || die "Directory $1 not found."
+  test -d "$1" || die "Directory $1 not found."
 }
 
 check_file() {
-    test -f $1 || die "File $1 not found."
+  test -f "$1" || die "File $1 not found."
 }
 
 run_test_locally() {
-    eval "$1" || true
+  eval "$1" || true
 }
 
 run_test_on_device() {
-    EXECFILE="$1"
-    LIBRARY="$2"
-    adb shell rm -rf $DEVICE_TMP
-    adb shell mkdir -p $DEVICE_TMP
-    adb push $EXECFILE $DEVICE_TMP > /dev/null
-    EXECPATH=$(basename $EXECFILE)
-    adb push $LIBRARY $DEVICE_TMP > /dev/null
-    adb shell "LD_LIBRARY_PATH=$DEVICE_TMP $DEVICE_TMP/$EXECPATH" || true
+  EXECFILE="$1"
+  LIBRARY="$2"
+  adb shell rm -rf "$DEVICE_TMP"
+  adb shell mkdir -p "$DEVICE_TMP"
+  adb push "$EXECFILE" "$DEVICE_TMP" > /dev/null
+  EXECPATH=$(basename "$EXECFILE")
+  adb push "$LIBRARY" "$DEVICE_TMP" > /dev/null
+  adb shell "LD_LIBRARY_PATH=$DEVICE_TMP" "$DEVICE_TMP/$EXECPATH" || true
 }
 
 device_integrity_break_test() {
-    go run $BORINGSSL/util/fipstools/break-hash.go $LIBCRYPTO_BIN ./libcrypto.so
-    $RUN $TEST_FIPS_BIN ./libcrypto.so
-    rm ./libcrypto.so
+  go run "$BORINGSSL/util/fipstools/break-hash.go" "$LIBCRYPTO_BIN" ./libcrypto.so
+  $RUN "$TEST_FIPS_BIN" ./libcrypto.so
+  rm ./libcrypto.so
 }
 
 local_integrity_break_test() {
-    go run $BORINGSSL/util/fipstools/break-hash.go $TEST_FIPS_BIN ./break-bin
-    chmod u+x ./break-bin
-    $RUN ./break-bin
-    rm ./break-bin
+  go run $BORINGSSL/util/fipstools/break-hash.go "$TEST_FIPS_BIN" ./break-bin
+  chmod u+x ./break-bin
+  $RUN ./break-bin
+  rm ./break-bin
+}
+
+local_runtime_break_test() {
+  BORINGSSL_FIPS_BREAK_TEST=$1 "$RUN" "$TEST_FIPS_BREAK_BIN"
 }
 
 # TODO(prb): make break-hash and break-kat take similar arguments to save having
 # separate functions for each.
 device_kat_break_test() {
-    KAT="$1"
-    go run $BORINGSSL/util/fipstools/break-kat.go $LIBCRYPTO_BIN $KAT > ./libcrypto.so
-    $RUN $TEST_FIPS_BIN ./libcrypto.so
-    rm ./libcrypto.so
+  KAT="$1"
+  go run "$BORINGSSL/util/fipstools/break-kat.go" "$LIBCRYPTO_BREAK_BIN" "$KAT" > ./libcrypto.so
+  $RUN "$TEST_FIPS_BIN" ./libcrypto.so
+  rm ./libcrypto.so
 }
 
 local_kat_break_test() {
-    KAT="$1"
-    go run $BORINGSSL/util/fipstools/break-kat.go $TEST_FIPS_BIN $KAT > ./break-bin
-    chmod u+x ./break-bin
-    $RUN ./break-bin
-    rm ./break-bin
+  KAT="$1"
+  go run "$BORINGSSL/util/fipstools/break-kat.go" "$TEST_FIPS_BREAK_BIN" "$KAT" > ./break-bin
+  chmod u+x ./break-bin
+  $RUN ./break-bin
+  rm ./break-bin
 }
 
 pause () {
-    echo -n "Press <Enter> "
-    read
+  echo -n "Press <Enter> "
+  read
 }
 
-if [ "$MODE" = "local" ]
-then
-    TEST_FIPS_BIN="build/util/fipstools/test_fips"
-    BORINGSSL=.
-    RUN=run_test_locally
-    BREAK_TEST=local_break_test
-    INTEGRITY_BREAK_TEST=local_integrity_break_test
-    KAT_BREAK_TEST=local_kat_break_test
-    if [ ! -f $TEST_FIPS_BIN ]; then
-	echo "$TEST_FIPS_BIN is missing. Run this script from the top level of a"
-	echo "BoringSSL checkout and ensure that BoringSSL has been built in"
-	echo "build/ with -DFIPS_BREAK_TEST=TESTS passed to CMake."
-	exit 1
-    fi
+if [ "$MODE" = "local" ]; then
+  TEST_FIPS_BIN=${TEST_FIPS_BIN:-build/util/fipstools/test_fips}
+  TEST_FIPS_BREAK_BIN=${TEST_FIPS_BREAK_BIN:-./test_fips_break}
+  check_file "$TEST_FIPS_BIN"
+  check_file "$TEST_FIPS_BREAK_BIN"
+
+  BORINGSSL=.
+  RUN=run_test_locally
+  BREAK_TEST=local_break_test
+  INTEGRITY_BREAK_TEST=local_integrity_break_test
+  KAT_BREAK_TEST=local_kat_break_test
+  RUNTIME_BREAK_TEST=local_runtime_break_test
+  if [ ! -f "$TEST_FIPS_BIN" ]; then
+    echo "$TEST_FIPS_BIN is missing. Run this script from the top level of a"
+    echo "BoringSSL checkout and ensure that BoringSSL has been built in"
+    echo "build/ with -DFIPS_BREAK_TEST=TESTS passed to CMake."
+    exit 1
+  fi
 else # Device mode
-    test "$ANDROID_BUILD_TOP" || die "'lunch aosp_arm64-eng' first"
-    check_directory "$ANDROID_PRODUCT_OUT"
+  test "$ANDROID_BUILD_TOP" || die "'lunch aosp_arm64-eng' first"
+  check_directory "$ANDROID_PRODUCT_OUT"
 
-    TEST_FIPS_BIN="$ANDROID_PRODUCT_OUT/system/bin/test_fips"
-    check_file "$TEST_FIPS_BIN"
-    LIBCRYPTO_BIN="$ANDROID_PRODUCT_OUT/system/lib64/libcrypto.so"
-    check_file "$LIBCRYPTO_BIN"
+  TEST_FIPS_BIN="$ANDROID_PRODUCT_OUT/system/bin/test_fips"
+  check_file "$TEST_FIPS_BIN"
+  LIBCRYPTO_BIN="$ANDROID_PRODUCT_OUT/system/lib64/libcrypto.so"
+  LIBCRYPTO_BREAK_BIN="libcrypto.so"
+  check_file "$LIBCRYPTO_BIN"
+  check_file "$LIBCRYPTO_BREAK_BIN"
 
-    test "$ANDROID_SERIAL" || die "ANDROID_SERIAL not set"
-    DEVICE_TMP=/data/local/tmp
+  test "$ANDROID_SERIAL" || die "ANDROID_SERIAL not set"
+  DEVICE_TMP=/data/local/tmp
 
-    BORINGSSL="$ANDROID_BUILD_TOP/external/boringssl/src"
-    RUN=run_test_on_device
-    INTEGRITY_BREAK_TEST=device_integrity_break_test
-    KAT_BREAK_TEST=device_kat_break_test
+  BORINGSSL="$ANDROID_BUILD_TOP/external/boringssl/src"
+  RUN=run_test_on_device
+  INTEGRITY_BREAK_TEST=device_integrity_break_test
+  KAT_BREAK_TEST=device_kat_break_test
 fi
 
 
-KATS=$(go run $BORINGSSL/util/fipstools/break-kat.go --list-tests)
+KATS=$(go run "$BORINGSSL/util/fipstools/break-kat.go" --list-tests)
 
 echo -e '\033[1mNormal output\033[0m'
-$RUN $TEST_FIPS_BIN $LIBCRYPTO_BIN
+$RUN "$TEST_FIPS_BIN" "$LIBCRYPTO_BIN"
 pause
 
 echo
@@ -171,3 +179,13 @@
   $KAT_BREAK_TEST $kat
   pause
 done
+
+if [ "$MODE" = "local" ]; then
+  # TODO(prb): add support for Android devices.
+  for runtime_test in ECDSA_PWCT RSA_PWCT CRNG; do
+    echo
+    echo -e "\033[1m${runtime_test} failure\033[0m"
+    $RUNTIME_BREAK_TEST ${runtime_test}
+    pause
+  done
+fi