xref: /aosp_15_r20/external/boringssl/src/util/fipstools/break-tests.sh (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
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