summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp159
-rw-r--r--CryptoNativeTests.xml (renamed from NativeTests.xml)9
-rw-r--r--SslNativeTests.xml33
-rwxr-xr-xUPDATING20
-rw-r--r--rules.mk19
-rw-r--r--src/crypto/fipsmodule/hmac/hmac.c1
-rw-r--r--src/crypto/x509/x509_test.cc106
-rw-r--r--src/crypto/x509/x509_vfy.c6
-rw-r--r--src/include/openssl/x509.h4
-rw-r--r--src/ssl/ssl_test.cc2
-rwxr-xr-xsrc/util/fipstools/break-tests.sh200
11 files changed, 515 insertions, 44 deletions
diff --git a/Android.bp b/Android.bp
index 40acf086..14c58d8b 100644
--- a/Android.bp
+++ b/Android.bp
@@ -60,15 +60,9 @@ cc_defaults {
"-Werror",
],
- c_std: "gnu11",
-
// Build BoringSSL and its tests against the same STL.
sdk_version: "9",
- target: {
- android: {
- stl: "libc++_static",
- },
- },
+ stl: "libc++_static",
}
// Used by libcrypto + libssl
@@ -109,8 +103,11 @@ cc_defaults {
},
local_include_dirs: ["src/crypto"],
+ stl: "none",
}
+// Boring Crypto Module object file.
+// Any changes here must also be reflected in bcm_object_for_testing below.
cc_object {
name: "bcm_object",
device_supported: true,
@@ -125,6 +122,7 @@ cc_object {
sanitize: {
address: false,
hwaddress: false,
+ memtag_stack: false,
fuzzer: false,
},
target: {
@@ -158,7 +156,7 @@ cc_object {
"com.android.art",
"com.android.art.debug",
"com.android.art.testing",
- "com.android.bluetooth",
+ "com.android.btservices",
"com.android.compos",
"com.android.conscrypt",
"com.android.resolv",
@@ -167,6 +165,55 @@ cc_object {
min_sdk_version: "29",
}
+// Version of bcm_object built with BORINGSSL_FIPS_BREAK_TESTS defined.
+// Only for use with the FIPS break-tests.sh script.
+// Must be kept in sync with bcm_object.
+cc_object {
+ name: "bcm_object_for_testing",
+ visibility: [
+ "//external/boringssl",
+ ],
+ device_supported: true,
+ defaults: [
+ "libcrypto_bcm_sources",
+ "libcrypto_defaults",
+ "boringssl_defaults",
+ "boringssl_flags",
+ ],
+ sanitize: {
+ address: false,
+ hwaddress: false,
+ fuzzer: false,
+ },
+ target: {
+ android: {
+ cflags: [
+ "-DBORINGSSL_FIPS",
+ "-DBORINGSSL_FIPS_BREAK_TESTS",
+ "-fPIC",
+ // -fno[data|text]-sections required to ensure a
+ // single text and data section for FIPS integrity check
+ "-fno-data-sections",
+ "-fno-function-sections",
+ ],
+ linker_script: "src/crypto/fipsmodule/fips_shared.lds",
+ },
+ // Temporary hack to let BoringSSL build with a new compiler.
+ // This doesn't enable HWASAN unconditionally, it just causes
+ // BoringSSL's asm code to unconditionally use a HWASAN-compatible
+ // global variable reference so that the non-HWASANified (because of
+ // sanitize: { hwaddress: false } above) code in the BCM can
+ // successfully link against the HWASANified code in the rest of
+ // BoringSSL in HWASAN builds.
+ android_arm64: {
+ asflags: [
+ "-fsanitize=hwaddress",
+ ],
+ },
+ },
+ min_sdk_version: "29",
+}
+
bootstrap_go_package {
name: "bssl_ar",
pkgPath: "boringssl.googlesource.com/boringssl/util/ar",
@@ -197,7 +244,8 @@ blueprint_go_binary {
],
}
-// Target and host library
+// Target and host library.
+// Any changes here must also be reflected in libcrypto_for_test below.
cc_library {
name: "libcrypto",
visibility: ["//visibility:public"],
@@ -246,7 +294,7 @@ cc_library {
"com.android.art",
"com.android.art.debug",
"com.android.art.testing",
- "com.android.bluetooth",
+ "com.android.btservices",
"com.android.compos",
"com.android.conscrypt",
"com.android.resolv",
@@ -255,6 +303,49 @@ cc_library {
min_sdk_version: "29",
}
+// Version of libcrypto build with BORINGSSL_FIPS_BREAK_TESTS defined
+// Only for use with the FIPS break-tests.sh script.
+// Must be kept in sync with libcrypto.
+cc_library {
+ name: "libcrypto_for_testing",
+ visibility: [
+ "//external/boringssl",
+ ],
+ defaults: [
+ "libcrypto_sources",
+ "libcrypto_defaults",
+ "boringssl_defaults",
+ "boringssl_flags",
+ ],
+ unique_host_soname: true,
+ srcs: [
+ ":bcm_object_for_testing",
+ ],
+ target: {
+ android: {
+ cflags: [
+ "-DBORINGSSL_FIPS",
+ "-DBORINGSSL_FIPS_BREAK_TESTS",
+ ],
+ sanitize: {
+ // Disable address sanitizing otherwise libcrypto will not report
+ // itself as being in FIPS mode, which causes boringssl_self_test
+ // to fail.
+ address: false,
+ },
+ inject_bssl_hash: true,
+ static: {
+ // Disable the static version of libcrypto, as it causes
+ // problems for FIPS certification. Use libcrypto_static for
+ // modules that need static libcrypto but do not need FIPS self
+ // testing, or use dynamic libcrypto.
+ enabled: false,
+ },
+ },
+ },
+ min_sdk_version: "29",
+}
+
// Static library
// This version of libcrypto will not have FIPS self tests enabled, so its
// usage is protected through visibility to ensure it doesn't end up used
@@ -278,6 +369,7 @@ cc_library_static {
"//hardware/interfaces/keymaster/4.0/vts/functional",
"//hardware/interfaces/keymaster/4.1/vts/functional",
"//packages/modules/adb",
+ "//packages/modules/Bluetooth:__subpackages__",
"//packages/modules/DnsResolver/tests:__subpackages__",
"//packages/modules/NeuralNetworks:__subpackages__",
"//system/core/init",
@@ -288,6 +380,7 @@ cc_library_static {
"//system/security/keystore/tests",
"//test/vts-testcase/security/avb",
],
+ min_sdk_version: "29",
apex_available: [
"//apex_available:platform",
"com.android.neuralnetworks",
@@ -301,6 +394,25 @@ cc_library_static {
],
}
+// Static library for use in bare-metal environments
+cc_library_static {
+ name: "libcrypto_baremetal",
+ defaults: [
+ "libcrypto_bcm_sources",
+ "libcrypto_sources",
+ "libcrypto_defaults",
+ "boringssl_defaults",
+ "boringssl_flags",
+ ],
+ cflags: [
+ "-DOPENSSL_NO_THREADS_CORRUPT_MEMORY_AND_LEAK_SECRETS_IF_THREADED",
+ "-DOPENSSL_SMALL",
+ "-DOPENSSL_NO_ASM",
+ ],
+ visibility: ["//packages/modules/Virtualization:__subpackages__"],
+ apex_available: ["com.android.virt"],
+}
+
// Common defaults for lib*_fuzz_unsafe. These are unsafe and deterministic
// libraries for testing and fuzzing only. See src/FUZZING.md.
cc_defaults {
@@ -363,10 +475,11 @@ cc_library {
apex_available: [
"//apex_available:platform",
- "com.android.bluetooth",
+ "com.android.btservices",
"com.android.adbd",
"com.android.conscrypt",
"com.android.resolv",
+ "com.android.virt",
],
min_sdk_version: "29",
}
@@ -486,14 +599,13 @@ cc_library_static {
shared_libs: [
"libcrypto",
- "libssl",
],
}
// Tests
cc_test {
name: "boringssl_crypto_test",
- test_config: "NativeTests.xml",
+ test_config: "CryptoNativeTests.xml",
host_supported: false,
per_testcase_directory: true,
compile_multilib: "both",
@@ -522,7 +634,7 @@ cc_test {
cc_test {
name: "boringssl_ssl_test",
- test_config: "NativeTests.xml",
+ test_config: "SslNativeTests.xml",
host_supported: false,
per_testcase_directory: true,
compile_multilib: "both",
@@ -565,6 +677,10 @@ cc_binary {
srcs: [
"src/util/fipstools/test_fips.c",
],
+ required: [
+ "adb",
+ "libcrypto_for_testing",
+ ],
}
// Rust bindings
@@ -603,6 +719,10 @@ rust_bindgen {
"libcrypto",
"libssl",
],
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.virt",
+ ],
}
// Encapsulate the bindgen-generated layout tests as a test target.
@@ -629,6 +749,10 @@ cc_library_static {
"libcrypto",
"libssl",
],
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.virt",
+ ],
}
// Replace the upstream CMake placeholder with a re-export of all of the local bindgen output.
@@ -653,7 +777,12 @@ rust_library {
// Since libbssl_sys_raw is not publically visible, we can't
// accidentally force a double-link by linking statically, so do so.
rlibs: ["libbssl_sys_raw"],
- static_libs: [
+ whole_static_libs: [
"libbssl_rust_support",
],
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.virt",
+ ],
}
+
diff --git a/NativeTests.xml b/CryptoNativeTests.xml
index d3eb9444..0adc18f2 100644
--- a/NativeTests.xml
+++ b/CryptoNativeTests.xml
@@ -14,26 +14,19 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
~
- ~ Re-runs a subset of MtsConscryptTestCases using Conscrypt's file-descriptor based
- ~ implementation to ensure there are no regressions in this implementation before
- ~ it is fully deprecated.
- ~
- ~ Apart from the include filters and SSLSocket implementation this test suite is
- ~ identical to MtsConscryptTestCases.
+ ~ Native test configuration for boringssl_crypto_test.
-->
<configuration description="Configuration for BoringSSL native tests">
<option name="test-suite-tag" value="mts-conscrypt" />
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
<option name="cleanup" value="true" />
<option name="push" value="boringssl_crypto_test->/data/local/tmp/boringssl_crypto_test" />
- <option name="push" value="boringssl_ssl_test->/data/local/tmp/boringssl_ssl_test" />
<option name="append-bitness" value="true" />
</target_preparer>
<target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
<test class="com.android.tradefed.testtype.GTest" >
<option name="native-test-device-path" value="/data/local/tmp" />
<option name="module-name" value="boringssl_crypto_test" />
- <option name="module-name" value="boringssl_ssl_test" />
<option name="runtime-hint" value="10m" />
<option name="native-test-timeout" value="600000" />
</test>
diff --git a/SslNativeTests.xml b/SslNativeTests.xml
new file mode 100644
index 00000000..9257111d
--- /dev/null
+++ b/SslNativeTests.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ ~
+ ~ Native test configuration for boringssl_ssl_test.
+ -->
+<configuration description="Configuration for BoringSSL native tests">
+ <option name="test-suite-tag" value="mts-conscrypt" />
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+ <option name="cleanup" value="true" />
+ <option name="push" value="boringssl_ssl_test->/data/local/tmp/boringssl_ssl_test" />
+ <option name="append-bitness" value="true" />
+ </target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="boringssl_ssl_test" />
+ <option name="runtime-hint" value="10m" />
+ <option name="native-test-timeout" value="600000" />
+ </test>
+</configuration>
diff --git a/UPDATING b/UPDATING
index 0266bfaa..12e890a7 100755
--- a/UPDATING
+++ b/UPDATING
@@ -2,14 +2,26 @@
set -xe
+# If a branch name is passed on the command line then sync
+# to that instead of HEAD.
+branch="$1"
+
old_revision=$(cat BORINGSSL_REVISION)
rm -Rf src
git clone https://boringssl.googlesource.com/boringssl src
cd src
+if [ "$branch" ]; then
+ git checkout "$branch"
+fi
new_revision=$(git show -s --pretty=%H)
+if [ "$branch" ]; then
+ target="branch $branch"
+else
+ target="$new_revision"
+fi
msgfile=$(mktemp)
-echo "external/boringssl: Sync to ${new_revision}.
+echo "external/boringssl: Sync to ${target}.
This includes the following changes:
@@ -24,8 +36,10 @@ git log --format='format:* %s%n%n%b' ${old_revision}..${new_revision} \
cd ..
echo "
-Test: atest CtsLibcoreTestCases CtsLibcoreOkHttpTestCases" >> $msgfile
-echo ${new_revision} > BORINGSSL_REVISION
+Test: atest CtsLibcoreTestCases CtsLibcoreOkHttpTestCases boringssl_crypto_test boringssl_ssl_test" >> $msgfile
+if [ ! "$branch" ]; then
+ echo ${new_revision} > BORINGSSL_REVISION
+fi
rm -Rf src/.git
rm -Rf src/fuzz
diff --git a/rules.mk b/rules.mk
index f0201223..3a600f3e 100644
--- a/rules.mk
+++ b/rules.mk
@@ -37,22 +37,6 @@ LOCAL_ADDITIONAL_DEPENDENCIES :=
MODULE_SRCDEPS += $(LOCAL_DIR)/crypto-sources.mk
include $(LOCAL_DIR)/crypto-sources.mk
-# Some files in BoringSSL use OS functions that aren't supported by Trusty. The
-# easiest way to deal with them is not to include them. As long as no path to
-# the functions defined in these files exists, the linker will be happy. If
-# such a path is created, it'll be a link-time error and something more complex
-# may need to be considered.
-LOCAL_SRC_FILES := $(filter-out src/crypto/bio/connect.c,$(LOCAL_SRC_FILES))
-LOCAL_SRC_FILES := $(filter-out src/crypto/bio/fd.c,$(LOCAL_SRC_FILES))
-LOCAL_SRC_FILES := $(filter-out src/crypto/bio/file.c,$(LOCAL_SRC_FILES))
-LOCAL_SRC_FILES := $(filter-out src/crypto/bio/socket.c,$(LOCAL_SRC_FILES))
-LOCAL_SRC_FILES := $(filter-out src/crypto/bio/socket_helper.c,$(LOCAL_SRC_FILES))
-LOCAL_SRC_FILES := $(filter-out src/crypto/x509/by_dir.c,$(LOCAL_SRC_FILES))
-
-# BoringSSL detects Trusty based on this define and does things like switch to
-# no-op threading functions.
-MODULE_CFLAGS += -DTRUSTY
-
# The AOSP stdatomic.h clang header does not build against musl. Disable C11
# atomics.
MODULE_CFLAGS += -D__STDC_NO_ATOMICS__
@@ -88,7 +72,6 @@ MODULE_INCLUDES += $(LOCAL_DIR)/src/crypto
MODULE_EXPORT_INCLUDES += $(LOCAL_DIR)/src/include
-MODULE_LIBRARY_DEPS += \
- trusty/user/base/lib/openssl-stubs \
+include trusty/user/base/lib/openssl-stubs/openssl-stubs-inc.mk
include make/library.mk
diff --git a/src/crypto/fipsmodule/hmac/hmac.c b/src/crypto/fipsmodule/hmac/hmac.c
index 454d0c0d..56e21b04 100644
--- a/src/crypto/fipsmodule/hmac/hmac.c
+++ b/src/crypto/fipsmodule/hmac/hmac.c
@@ -63,6 +63,7 @@
#include <openssl/mem.h>
#include "../../internal.h"
+#include "../service_indicator/internal.h"
uint8_t *HMAC(const EVP_MD *evp_md, const void *key, size_t key_len,
diff --git a/src/crypto/x509/x509_test.cc b/src/crypto/x509/x509_test.cc
index ce70ae3b..379f26bc 100644
--- a/src/crypto/x509/x509_test.cc
+++ b/src/crypto/x509/x509_test.cc
@@ -1470,6 +1470,23 @@ TEST(X509Test, TestCRL) {
Verify(leaf.get(), {root.get()}, {root.get()},
{algorithm_mismatch_crl2.get()}, X509_V_FLAG_CRL_CHECK));
+ // The CRL is valid for a month.
+ EXPECT_EQ(X509_V_ERR_CRL_HAS_EXPIRED,
+ Verify(leaf.get(), {root.get()}, {root.get()}, {basic_crl.get()},
+ X509_V_FLAG_CRL_CHECK, [](X509_VERIFY_PARAM *param) {
+ X509_VERIFY_PARAM_set_time(
+ param, kReferenceTime + 2 * 30 * 24 * 3600);
+ }));
+
+ // X509_V_FLAG_NO_CHECK_TIME suppresses the validity check.
+ EXPECT_EQ(X509_V_OK,
+ Verify(leaf.get(), {root.get()}, {root.get()}, {basic_crl.get()},
+ X509_V_FLAG_CRL_CHECK | X509_V_FLAG_NO_CHECK_TIME,
+ [](X509_VERIFY_PARAM *param) {
+ X509_VERIFY_PARAM_set_time(
+ param, kReferenceTime + 2 * 30 * 24 * 3600);
+ }));
+
// Parsing kBadExtensionCRL should fail.
EXPECT_FALSE(CRLFromPEM(kBadExtensionCRL));
}
@@ -3551,6 +3568,95 @@ TEST(X509Test, TrustedFirst) {
}));
}
+// Test that notBefore and notAfter checks work correctly.
+TEST(X509Test, Expiry) {
+ bssl::UniquePtr<EVP_PKEY> key = PrivateKeyFromPEM(kP256Key);
+ ASSERT_TRUE(key);
+
+ // The following are measured in seconds relative to kReferenceTime. The
+ // validity periods are staggered so we can independently test both leaf and
+ // root time checks.
+ const time_t kSecondsInDay = 24 * 3600;
+ const time_t kRootStart = -30 * kSecondsInDay;
+ const time_t kIntermediateStart = -20 * kSecondsInDay;
+ const time_t kLeafStart = -10 * kSecondsInDay;
+ const time_t kIntermediateEnd = 10 * kSecondsInDay;
+ const time_t kLeafEnd = 20 * kSecondsInDay;
+ const time_t kRootEnd = 30 * kSecondsInDay;
+
+ bssl::UniquePtr<X509> root =
+ MakeTestCert("Root", "Root", key.get(), /*is_ca=*/true);
+ ASSERT_TRUE(root);
+ ASSERT_TRUE(ASN1_TIME_adj(X509_getm_notBefore(root.get()), kReferenceTime,
+ /*offset_day=*/0,
+ /*offset_sec=*/kRootStart));
+ ASSERT_TRUE(ASN1_TIME_adj(X509_getm_notAfter(root.get()), kReferenceTime,
+ /*offset_day=*/0,
+ /*offset_sec=*/kRootEnd));
+ ASSERT_TRUE(X509_sign(root.get(), key.get(), EVP_sha256()));
+
+ bssl::UniquePtr<X509> intermediate =
+ MakeTestCert("Root", "Intermediate", key.get(), /*is_ca=*/true);
+ ASSERT_TRUE(intermediate);
+ ASSERT_TRUE(ASN1_TIME_adj(X509_getm_notBefore(intermediate.get()),
+ kReferenceTime,
+ /*offset_day=*/0,
+ /*offset_sec=*/kIntermediateStart));
+ ASSERT_TRUE(ASN1_TIME_adj(X509_getm_notAfter(intermediate.get()),
+ kReferenceTime,
+ /*offset_day=*/0,
+ /*offset_sec=*/kIntermediateEnd));
+ ASSERT_TRUE(X509_sign(intermediate.get(), key.get(), EVP_sha256()));
+
+ bssl::UniquePtr<X509> leaf =
+ MakeTestCert("Intermediate", "Leaf", key.get(), /*is_ca=*/false);
+ ASSERT_TRUE(leaf);
+ ASSERT_TRUE(ASN1_TIME_adj(X509_getm_notBefore(leaf.get()), kReferenceTime,
+ /*offset_day=*/0,
+ /*offset_sec=*/kLeafStart));
+ ASSERT_TRUE(ASN1_TIME_adj(X509_getm_notAfter(leaf.get()), kReferenceTime,
+ /*offset_day=*/0,
+ /*offset_sec=*/kLeafEnd));
+ ASSERT_TRUE(X509_sign(leaf.get(), key.get(), EVP_sha256()));
+
+ struct VerifyAt {
+ time_t time;
+ void operator()(X509_VERIFY_PARAM *param) const {
+ X509_VERIFY_PARAM_set_time(param, time);
+ }
+ };
+
+ for (bool check_time : {true, false}) {
+ SCOPED_TRACE(check_time);
+ unsigned long flags = check_time ? 0 : X509_V_FLAG_NO_CHECK_TIME;
+ int not_yet_valid = check_time ? X509_V_ERR_CERT_NOT_YET_VALID : X509_V_OK;
+ int has_expired = check_time ? X509_V_ERR_CERT_HAS_EXPIRED : X509_V_OK;
+
+ EXPECT_EQ(not_yet_valid,
+ Verify(leaf.get(), {root.get()}, {intermediate.get()}, {}, flags,
+ VerifyAt{kReferenceTime + kRootStart - 1}));
+ EXPECT_EQ(not_yet_valid,
+ Verify(leaf.get(), {root.get()}, {intermediate.get()}, {}, flags,
+ VerifyAt{kReferenceTime + kIntermediateStart - 1}));
+ EXPECT_EQ(not_yet_valid,
+ Verify(leaf.get(), {root.get()}, {intermediate.get()}, {}, flags,
+ VerifyAt{kReferenceTime + kLeafStart - 1}));
+
+ EXPECT_EQ(X509_V_OK, Verify(leaf.get(), {root.get()}, {intermediate.get()},
+ {}, flags, VerifyAt{kReferenceTime}));
+
+ EXPECT_EQ(has_expired,
+ Verify(leaf.get(), {root.get()}, {intermediate.get()}, {}, flags,
+ VerifyAt{kReferenceTime + kRootEnd + 1}));
+ EXPECT_EQ(has_expired,
+ Verify(leaf.get(), {root.get()}, {intermediate.get()}, {}, flags,
+ VerifyAt{kReferenceTime + kIntermediateEnd + 1}));
+ EXPECT_EQ(has_expired,
+ Verify(leaf.get(), {root.get()}, {intermediate.get()}, {}, flags,
+ VerifyAt{kReferenceTime + kLeafEnd + 1}));
+ }
+}
+
// kConstructedBitString is an X.509 certificate where the signature is encoded
// as a BER constructed BIT STRING. Note that, while OpenSSL's parser accepts
// this input, it interprets the value incorrectly.
diff --git a/src/crypto/x509/x509_vfy.c b/src/crypto/x509/x509_vfy.c
index f41ae6e1..7dcac260 100644
--- a/src/crypto/x509/x509_vfy.c
+++ b/src/crypto/x509/x509_vfy.c
@@ -1000,6 +1000,9 @@ static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify)
{
time_t *ptime;
int i;
+ if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME) {
+ return 1;
+ }
if (notify)
ctx->current_crl = crl;
if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
@@ -1743,6 +1746,9 @@ static int check_cert_time(X509_STORE_CTX *ctx, X509 *x)
time_t *ptime;
int i;
+ if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME) {
+ return 1;
+ }
if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
ptime = &ctx->param->check_time;
else
diff --git a/src/include/openssl/x509.h b/src/include/openssl/x509.h
index 4d312c7e..608c6700 100644
--- a/src/include/openssl/x509.h
+++ b/src/include/openssl/x509.h
@@ -2071,6 +2071,10 @@ OPENSSL_EXPORT void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
// will force the behaviour to match that of previous versions.
#define X509_V_FLAG_NO_ALT_CHAINS 0x100000
+// X509_V_FLAG_NO_CHECK_TIME disables all time checks in certificate
+// verification.
+#define X509_V_FLAG_NO_CHECK_TIME 0x200000
+
#define X509_VP_FLAG_DEFAULT 0x1
#define X509_VP_FLAG_OVERWRITE 0x2
#define X509_VP_FLAG_RESET_FLAGS 0x4
diff --git a/src/ssl/ssl_test.cc b/src/ssl/ssl_test.cc
index e2db5a4d..f07196cf 100644
--- a/src/ssl/ssl_test.cc
+++ b/src/ssl/ssl_test.cc
@@ -8064,6 +8064,8 @@ RVHWbCvFvNZAoWiIJ2z34RLGInyZvCZ8xLAvsuaWULDDaoeDl1M0t4Hm
SSL_CTX_set_verify(client_ctx.get(),
SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
nullptr);
+ X509_VERIFY_PARAM_set_flags(SSL_CTX_get0_param(client_ctx.get()),
+ X509_V_FLAG_NO_CHECK_TIME);
struct TestCase {
X509 *cert;
diff --git a/src/util/fipstools/break-tests.sh b/src/util/fipstools/break-tests.sh
new file mode 100755
index 00000000..f33c4c6f
--- /dev/null
+++ b/src/util/fipstools/break-tests.sh
@@ -0,0 +1,200 @@
+# Copyright (c) 2022, Google Inc.
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+# This script runs test_fips repeatedly with different FIPS tests broken. It is
+# intended to be observed to demonstrate that the various tests are working and
+# thus pauses for a keystroke between tests.
+#
+# Runs in either device mode (on an attached Android device) or in a locally built
+# BoringSSL checkout.
+#
+# On Android static binaries are not built using FIPS mode, so in device mode each
+# test makes changes to libcrypto.so rather than the test binary, test_fips.
+
+set -e
+
+die () {
+ echo "ERROR: $@"
+ exit 1
+}
+
+usage() {
+ 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
+}
+
+# Prefer mode from command line if present.
+case "$1" in
+ local|device)
+ MODE=$1
+ ;;
+
+ "")
+ MODE=`inferred_mode`
+ ;;
+
+ *)
+ usage
+ ;;
+esac
+
+check_directory() {
+ test -d $1 || die "Directory $1 not found."
+}
+
+check_file() {
+ test -f $1 || die "File $1 not found."
+}
+
+run_test_locally() {
+ 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
+ CMD="LD_LIBRARY_PATH=$DEVICE_TMP $DEVICE_TMP/$EXECPATH"
+ if [ "$BORINGSSL_FIPS_BREAK_TEST" ]; then
+ CMD="BORINGSSL_FIPS_BREAK_TEST=$BORINGSSL_FIPS_BREAK_TEST $CMD"
+ fi
+ adb shell "$CMD" || 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
+}
+
+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
+}
+
+local_runtime_break_test() {
+ BORINGSSL_FIPS_BREAK_TEST=$1 $RUN $TEST_FIPS_BREAK_BIN
+}
+
+device_runtime_break_test() {
+ cp $LIBCRYPTO_BREAK_BIN ./libcrypto.so
+ BORINGSSL_FIPS_BREAK_TEST=$1 $RUN $TEST_FIPS_BIN ./libcrypto.so
+ rm ./libcrypto.so
+}
+
+# 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_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_BREAK_BIN $KAT > ./break-bin
+ chmod u+x ./break-bin
+ $RUN ./break-bin
+ rm ./break-bin
+}
+
+pause () {
+ echo -n "Press <Enter> "
+ read
+}
+
+if [ "$MODE" = "local" ]; then
+ TEST_FIPS_BIN=${TEST_FIPS_BIN:-build/util/fipstools/test_fips}
+ check_file $TEST_FIPS_BIN
+
+ TEST_FIPS_BREAK_BIN=${TEST_FIPS_BREAK_BIN:-./test_fips_break}
+ if [ ! -f $TEST_FIPS_BREAK_BIN ]; then
+ echo "$TEST_FIPS_BREAK_BIN is missing. Build BoringSSL with "
+ echo "-DFIPS_BREAK_TEST=TESTS passed to CMake and copy the resulting"
+ echo "test_fips binary to $TEST_FIPS_BREAK_BIN."
+ exit 1
+ fi
+
+ 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
+else # Device mode
+ test "$ANDROID_BUILD_TOP" || die "'lunch aosp_arm64-eng' first"
+ check_directory "$ANDROID_PRODUCT_OUT"
+ test "$TARGET_PRODUCT" = "aosp_arm64" || die "Lunch target is $TARGET_PRODUCT not aosp_arm64"
+
+ 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="$ANDROID_PRODUCT_OUT/system/lib64/libcrypto_for_testing.so"
+ check_file "$LIBCRYPTO_BIN"
+ check_file "$LIBCRYPTO_BREAK_BIN"
+
+ 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
+ RUNTIME_BREAK_TEST=device_runtime_break_test
+fi
+
+
+KATS=$(go run $BORINGSSL/util/fipstools/break-kat.go --list-tests)
+
+echo -e '\033[1mNormal output\033[0m'
+$RUN $TEST_FIPS_BIN $LIBCRYPTO_BIN
+pause
+
+echo
+echo -e '\033[1mIntegrity test failure\033[0m'
+$INTEGRITY_BREAK_TEST
+pause
+
+for kat in $KATS; do
+ echo
+ echo -e "\033[1mKAT failure ${kat}\033[0m"
+ $KAT_BREAK_TEST $kat
+ pause
+done
+
+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