diff --git a/.bcr/metadata.template.json b/.bcr/metadata.template.json index 6d8f767..ed376c9 100644 --- a/.bcr/metadata.template.json +++ b/.bcr/metadata.template.json
@@ -7,14 +7,14 @@ "name": "Adam Langley" }, { - "email": "bbe@google.com", - "github": "bob-beck", - "name": "Bob Beck" - }, - { "email": "davidben@google.com", "github": "davidben", "name": "David Benjamin" + }, + { + "email": "dadrian@google.com", + "github": "dadrian", + "name": "David Adrian" } ], "repository": [
diff --git a/CMakeLists.txt b/CMakeLists.txt index 82b19fc..4211db0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -36,6 +36,9 @@ enable_language(C) enable_language(CXX) +# TODO(crbug,com/389897612): Register tests with CTest. For now, we include this +# only to pick up the standard |BUILD_TESTING| option. +include(CTest) include(GNUInstallDirs) set(INSTALL_ENABLED 1) @@ -476,33 +479,33 @@ target_link_libraries(libcxx libcxxabi) endif() -# Add minimal googletest targets. The provided one has many side-effects, and -# googletest has a very straightforward build. -add_library( - boringssl_gtest - third_party/googletest/googlemock/src/gmock-all.cc - third_party/googletest/googletest/src/gtest-all.cc -) -if(USE_CUSTOM_LIBCXX) - target_link_libraries(boringssl_gtest libcxx) -endif() -target_include_directories( +if(BUILD_TESTING) + # Add minimal googletest targets. The provided one has many side-effects, and + # googletest has a very straightforward build. + add_library( boringssl_gtest - PUBLIC - third_party/googletest/googlemock/include - third_party/googletest/googletest/include - PRIVATE - third_party/googletest/googlemock - third_party/googletest/googletest -) + third_party/googletest/googlemock/src/gmock-all.cc + third_party/googletest/googletest/src/gtest-all.cc + ) + if(USE_CUSTOM_LIBCXX) + target_link_libraries(boringssl_gtest libcxx) + endif() + target_include_directories( + boringssl_gtest + PUBLIC + third_party/googletest/googlemock/include + third_party/googletest/googletest/include + PRIVATE + third_party/googletest/googlemock + third_party/googletest/googletest + ) -# Declare a dummy target to build all unit tests. Test targets should inject -# themselves as dependencies next to the target definition. -add_custom_target(all_tests) + # Declare a dummy target to build all unit tests. Test targets should inject + # themselves as dependencies next to the target definition. + add_custom_target(all_tests) -add_subdirectory(ssl/test) -add_subdirectory(util/fipstools) -add_subdirectory(util/fipstools/acvp/modulewrapper) + add_subdirectory(ssl/test) +endif() if(OPENSSL_ASM) set(CRYPTO_SOURCES_ASM_USED ${CRYPTO_SOURCES_ASM}) @@ -658,64 +661,62 @@ add_library(decrepit ${DECREPIT_SOURCES}) target_link_libraries(decrepit ssl crypto) -add_library(test_support_lib STATIC - ${TEST_SUPPORT_SOURCES} ${TEST_SUPPORT_SOURCES_ASM_USED}) -if(LIBUNWIND_FOUND) - target_compile_options(test_support_lib PRIVATE ${LIBUNWIND_CFLAGS_OTHER}) - target_include_directories(test_support_lib PRIVATE ${LIBUNWIND_INCLUDE_DIRS}) - target_link_libraries(test_support_lib ${LIBUNWIND_LDFLAGS}) -endif() -if(WIN32) - target_link_libraries(test_support_lib dbghelp) -endif() -target_link_libraries(test_support_lib boringssl_gtest crypto) - -# urandom_test is a separate binary because it needs to be able to observe the -# PRNG initialisation, which means that it can't have other tests running before -# it does. -add_executable(urandom_test ${URANDOM_TEST_SOURCES}) -target_link_libraries(urandom_test test_support_lib boringssl_gtest crypto) -add_dependencies(all_tests urandom_test) - -add_executable(crypto_test ${CRYPTO_TEST_SOURCES}) -target_link_libraries(crypto_test test_support_lib boringssl_gtest crypto) -add_dependencies(all_tests crypto_test) - -add_executable(ssl_test ${SSL_TEST_SOURCES}) -target_link_libraries(ssl_test test_support_lib boringssl_gtest ssl crypto) -add_dependencies(all_tests ssl_test) -add_executable(decrepit_test ${DECREPIT_TEST_SOURCES}) -target_link_libraries(decrepit_test test_support_lib boringssl_gtest - decrepit ssl crypto) -add_dependencies(all_tests decrepit_test) - if(APPLE) set(PKI_CXX_FLAGS "-fno-aligned-new") endif() - add_library(pki ${PKI_SOURCES}) target_link_libraries(pki crypto) +target_compile_options(pki PRIVATE ${PKI_CXX_FLAGS}) -add_executable(pki_test ${PKI_TEST_SOURCES}) -target_link_libraries(pki_test test_support_lib boringssl_gtest pki crypto) -add_dependencies(all_tests pki_test) +if(BUILD_TESTING) + add_library(test_support_lib STATIC + ${TEST_SUPPORT_SOURCES} ${TEST_SUPPORT_SOURCES_ASM_USED}) + if(LIBUNWIND_FOUND) + target_compile_options(test_support_lib PRIVATE ${LIBUNWIND_CFLAGS_OTHER}) + target_include_directories(test_support_lib PRIVATE ${LIBUNWIND_INCLUDE_DIRS}) + target_link_libraries(test_support_lib ${LIBUNWIND_LDFLAGS}) + endif() + if(WIN32) + target_link_libraries(test_support_lib dbghelp) + endif() + target_link_libraries(test_support_lib boringssl_gtest crypto) -set_target_properties( - pki pki_test - PROPERTIES - COMPILE_FLAGS "${PKI_CXX_FLAGS}") + # urandom_test is a separate binary because it needs to be able to observe the + # PRNG initialisation, which means that it can't have other tests running before + # it does. + add_executable(urandom_test ${URANDOM_TEST_SOURCES}) + target_link_libraries(urandom_test test_support_lib boringssl_gtest crypto) + add_dependencies(all_tests urandom_test) + + add_executable(crypto_test ${CRYPTO_TEST_SOURCES}) + target_link_libraries(crypto_test test_support_lib boringssl_gtest crypto) + add_dependencies(all_tests crypto_test) + + add_executable(ssl_test ${SSL_TEST_SOURCES}) + target_link_libraries(ssl_test test_support_lib boringssl_gtest ssl crypto) + add_dependencies(all_tests ssl_test) + add_executable(decrepit_test ${DECREPIT_TEST_SOURCES}) + target_link_libraries(decrepit_test test_support_lib boringssl_gtest + decrepit ssl crypto) + add_dependencies(all_tests decrepit_test) + + add_executable(pki_test ${PKI_TEST_SOURCES}) + target_link_libraries(pki_test test_support_lib boringssl_gtest pki crypto) + target_compile_options(pki_test PRIVATE ${PKI_CXX_FLAGS}) + add_dependencies(all_tests pki_test) + + add_executable(test_fips util/fipstools/test_fips.cc) + target_link_libraries(test_fips crypto) +endif() + +if(FIPS) + add_executable(modulewrapper ${MODULEWRAPPER_SOURCES}) + target_link_libraries(modulewrapper crypto) +endif() add_executable(bssl ${BSSL_SOURCES}) target_link_libraries(bssl ssl crypto) -# Historically, targets were built in subdirectories. For compatibility with -# existing tools, we, for now, copy the targets into the subdirectories. This -# will be removed sometime in 2024. -copy_post_build(crypto crypto crypto_test urandom_test) -copy_post_build(ssl ssl ssl_test) -copy_post_build(decrepit decrepit decrepit_test) -copy_post_build(tool bssl) - if(FUZZ) if(LIBFUZZER_FROM_DEPS) file(GLOB LIBFUZZER_SOURCES "util/bot/libFuzzer/*.cpp") @@ -744,56 +745,58 @@ set(HANDSHAKER_ARGS "-handshaker-path" $<TARGET_FILE:handshaker>) endif() -if(FIPS) - add_custom_target( - acvp_tests - COMMAND ${GO_EXECUTABLE} build -o ${CMAKE_CURRENT_BINARY_DIR}/acvptool - boringssl.googlesource.com/boringssl.git/util/fipstools/acvp/acvptool - COMMAND ${GO_EXECUTABLE} build -o ${CMAKE_CURRENT_BINARY_DIR}/testmodulewrapper - boringssl.googlesource.com/boringssl.git/util/fipstools/acvp/acvptool/testmodulewrapper - COMMAND cd util/fipstools/acvp/acvptool/test && - ${GO_EXECUTABLE} run check_expected.go - -tool ${CMAKE_CURRENT_BINARY_DIR}/acvptool - -module-wrappers modulewrapper:$<TARGET_FILE:modulewrapper>,testmodulewrapper:${CMAKE_CURRENT_BINARY_DIR}/testmodulewrapper - -tests tests.json - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - DEPENDS modulewrapper - USES_TERMINAL) - - add_custom_target( - fips_specific_tests_if_any - DEPENDS acvp_tests - ) -else() - add_custom_target(fips_specific_tests_if_any) -endif() - -file(STRINGS util/go_tests.txt GO_TESTS) -set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS - util/go_tests.txt) - -if(GO_EXECUTABLE) - add_custom_target( - run_tests - COMMAND ${CMAKE_COMMAND} -E echo "Running Go tests" - COMMAND ${GO_EXECUTABLE} test ${GO_TESTS} - COMMAND ${CMAKE_COMMAND} -E echo - COMMAND ${CMAKE_COMMAND} -E echo "Running unit tests" - COMMAND ${GO_EXECUTABLE} run util/all_tests.go -build-dir - ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E echo - COMMAND ${CMAKE_COMMAND} -E echo "Running SSL tests" - COMMAND cd ssl/test/runner && - ${GO_EXECUTABLE} test -shim-path $<TARGET_FILE:bssl_shim> - ${HANDSHAKER_ARGS} ${RUNNER_ARGS} +if(BUILD_TESTING) + if(FIPS) + add_custom_target( + acvp_tests + COMMAND ${GO_EXECUTABLE} build -o ${CMAKE_CURRENT_BINARY_DIR}/acvptool + boringssl.googlesource.com/boringssl.git/util/fipstools/acvp/acvptool + COMMAND ${GO_EXECUTABLE} build -o ${CMAKE_CURRENT_BINARY_DIR}/testmodulewrapper + boringssl.googlesource.com/boringssl.git/util/fipstools/acvp/acvptool/testmodulewrapper + COMMAND cd util/fipstools/acvp/acvptool/test && + ${GO_EXECUTABLE} run check_expected.go + -tool ${CMAKE_CURRENT_BINARY_DIR}/acvptool + -module-wrappers modulewrapper:$<TARGET_FILE:modulewrapper>,testmodulewrapper:${CMAKE_CURRENT_BINARY_DIR}/testmodulewrapper + -tests tests.json WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - DEPENDS all_tests bssl_shim handshaker fips_specific_tests_if_any + DEPENDS modulewrapper USES_TERMINAL) -else() - add_custom_target( - run_tests - COMMAND ${CMAKE_COMMAND} -E echo "Running tests requires Go" - COMMAND ${CMAKE_COMMAND} -E false) + + add_custom_target( + fips_specific_tests_if_any + DEPENDS acvp_tests + ) + else() + add_custom_target(fips_specific_tests_if_any) + endif() + + file(STRINGS util/go_tests.txt GO_TESTS) + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS + util/go_tests.txt) + + if(GO_EXECUTABLE) + add_custom_target( + run_tests + COMMAND ${CMAKE_COMMAND} -E echo "Running Go tests" + COMMAND ${GO_EXECUTABLE} test ${GO_TESTS} + COMMAND ${CMAKE_COMMAND} -E echo + COMMAND ${CMAKE_COMMAND} -E echo "Running unit tests" + COMMAND ${GO_EXECUTABLE} run util/all_tests.go -build-dir + ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E echo + COMMAND ${CMAKE_COMMAND} -E echo "Running SSL tests" + COMMAND cd ssl/test/runner && + ${GO_EXECUTABLE} test -shim-path $<TARGET_FILE:bssl_shim> + ${HANDSHAKER_ARGS} ${RUNNER_ARGS} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + DEPENDS all_tests bssl_shim handshaker fips_specific_tests_if_any + USES_TERMINAL) + else() + add_custom_target( + run_tests + COMMAND ${CMAKE_COMMAND} -E echo "Running tests requires Go" + COMMAND ${CMAKE_COMMAND} -E false) + endif() endif() if(INSTALL_ENABLED)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e6f9471..4d9279a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md
@@ -41,7 +41,7 @@ git push origin HEAD:refs/for/main The output will then give you a link to the change. Add `agl@google.com`, -`davidben@google.com`, and `bbe@google.com` as reviewers. +`davidben@google.com` as reviewers. Pushing a commit with the same Change-Id as an existing change will upload a new version of it. (Use the `git rebase` or `git commit --amend` commands.)
diff --git a/MODULE.bazel b/MODULE.bazel index 7d06db0..6737496 100644 --- a/MODULE.bazel +++ b/MODULE.bazel
@@ -16,7 +16,7 @@ # the revision where we bump the version. module( name = "boringssl", - version = "0.20250311.0", + version = "0.20250415.0", compatibility_level = 2, )
diff --git a/build.json b/build.json index cbe98b4..67d3992 100644 --- a/build.json +++ b/build.json
@@ -204,7 +204,9 @@ "crypto/blake2/blake2.cc", "crypto/bn/bn_asn1.cc", "crypto/bn/convert.cc", + "crypto/bn/div.cc", "crypto/bn/exponentiation.cc", + "crypto/bn/sqrt.cc", "crypto/buf/buf.cc", "crypto/bytestring/asn1_compat.cc", "crypto/bytestring/ber.cc", @@ -1054,5 +1056,14 @@ "rust/bssl-crypto/src/*.rs", "rust/bssl-crypto/src/*/*.rs" ] + }, + "modulewrapper": { + "srcs": [ + "util/fipstools/acvp/modulewrapper/main.cc", + "util/fipstools/acvp/modulewrapper/modulewrapper.cc" + ], + "internal_hdrs": [ + "util/fipstools/acvp/modulewrapper/modulewrapper.h" + ] } }
diff --git a/crypto/bn/convert.cc b/crypto/bn/convert.cc index 6f4d4fa..59ea6d4 100644 --- a/crypto/bn/convert.cc +++ b/crypto/bn/convert.cc
@@ -19,6 +19,8 @@ #include <limits.h> #include <stdio.h> +#include <algorithm> + #include <openssl/bio.h> #include <openssl/bytestring.h> #include <openssl/err.h> @@ -196,33 +198,32 @@ char *BN_bn2dec(const BIGNUM *a) { // It is easier to print strings little-endian, so we assemble it in reverse // and fix at the end. - BIGNUM *copy = NULL; - CBB cbb; - if (!CBB_init(&cbb, 16) || // - !CBB_add_u8(&cbb, 0 /* trailing NUL */)) { - goto err; + bssl::ScopedCBB cbb; + if (!CBB_init(cbb.get(), 16) || // + !CBB_add_u8(cbb.get(), 0 /* trailing NUL */)) { + return nullptr; } if (BN_is_zero(a)) { - if (!CBB_add_u8(&cbb, '0')) { - goto err; + if (!CBB_add_u8(cbb.get(), '0')) { + return nullptr; } } else { - copy = BN_dup(a); - if (copy == NULL) { - goto err; + bssl::UniquePtr<BIGNUM> copy(BN_dup(a)); + if (copy == nullptr) { + return nullptr; } - while (!BN_is_zero(copy)) { - BN_ULONG word = BN_div_word(copy, BN_DEC_CONV); + while (!BN_is_zero(copy.get())) { + BN_ULONG word = BN_div_word(copy.get(), BN_DEC_CONV); if (word == (BN_ULONG)-1) { - goto err; + return nullptr; } - const int add_leading_zeros = !BN_is_zero(copy); + const int add_leading_zeros = !BN_is_zero(copy.get()); for (int i = 0; i < BN_DEC_NUM && (add_leading_zeros || word != 0); i++) { - if (!CBB_add_u8(&cbb, '0' + word % 10)) { - goto err; + if (!CBB_add_u8(cbb.get(), '0' + word % 10)) { + return nullptr; } word /= 10; } @@ -231,30 +232,18 @@ } if (BN_is_negative(a) && // - !CBB_add_u8(&cbb, '-')) { - goto err; + !CBB_add_u8(cbb.get(), '-')) { + return nullptr; } uint8_t *data; size_t len; - if (!CBB_finish(&cbb, &data, &len)) { - goto err; + if (!CBB_finish(cbb.get(), &data, &len)) { + return nullptr; } - // Reverse the buffer. - for (size_t i = 0; i < len / 2; i++) { - uint8_t tmp = data[i]; - data[i] = data[len - 1 - i]; - data[len - 1 - i] = tmp; - } - - BN_free(copy); - return (char *)data; - -err: - BN_free(copy); - CBB_cleanup(&cbb); - return NULL; + std::reverse(data, data + len); + return reinterpret_cast<char *>(data); } int BN_dec2bn(BIGNUM **outp, const char *in) { @@ -285,33 +274,28 @@ } int BN_print(BIO *bp, const BIGNUM *a) { - int i, j, v, z = 0; - int ret = 0; - if (a->neg && BIO_write(bp, "-", 1) != 1) { - goto end; + return 0; } if (BN_is_zero(a) && BIO_write(bp, "0", 1) != 1) { - goto end; + return 0; } - for (i = bn_minimal_width(a) - 1; i >= 0; i--) { - for (j = BN_BITS2 - 4; j >= 0; j -= 4) { + int z = 0; + for (int i = bn_minimal_width(a) - 1; i >= 0; i--) { + for (int j = BN_BITS2 - 4; j >= 0; j -= 4) { // strip leading zeros - v = ((int)(a->d[i] >> (long)j)) & 0x0f; + int v = ((int)(a->d[i] >> (long)j)) & 0x0f; if (z || v != 0) { if (BIO_write(bp, &hextable[v], 1) != 1) { - goto end; + return 0; } z = 1; } } } - ret = 1; - -end: - return ret; + return 1; } int BN_print_fp(FILE *fp, const BIGNUM *a) {
diff --git a/crypto/bn/div.cc b/crypto/bn/div.cc new file mode 100644 index 0000000..868a2a3 --- /dev/null +++ b/crypto/bn/div.cc
@@ -0,0 +1,100 @@ +// Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. +// +// 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 +// +// https://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. + +#include <openssl/bn.h> + +#include <openssl/err.h> + +#include "../fipsmodule/bn/internal.h" +#include "../internal.h" + + +int BN_mod_pow2(BIGNUM *r, const BIGNUM *a, size_t e) { + if (e == 0 || a->width == 0) { + BN_zero(r); + return 1; + } + + size_t num_words = 1 + ((e - 1) / BN_BITS2); + + // If |a| definitely has less than |e| bits, just BN_copy. + if ((size_t)a->width < num_words) { + return BN_copy(r, a) != NULL; + } + + // Otherwise, first make sure we have enough space in |r|. + // Note that this will fail if num_words > INT_MAX. + if (!bn_wexpand(r, num_words)) { + return 0; + } + + // Copy the content of |a| into |r|. + OPENSSL_memcpy(r->d, a->d, num_words * sizeof(BN_ULONG)); + + // If |e| isn't word-aligned, we have to mask off some of our bits. + size_t top_word_exponent = e % (sizeof(BN_ULONG) * 8); + if (top_word_exponent != 0) { + r->d[num_words - 1] &= (((BN_ULONG)1) << top_word_exponent) - 1; + } + + // Fill in the remaining fields of |r|. + r->neg = a->neg; + r->width = (int)num_words; + bn_set_minimal_width(r); + return 1; +} + +int BN_nnmod_pow2(BIGNUM *r, const BIGNUM *a, size_t e) { + if (!BN_mod_pow2(r, a, e)) { + return 0; + } + + // If the returned value was non-negative, we're done. + if (BN_is_zero(r) || !r->neg) { + return 1; + } + + size_t num_words = 1 + (e - 1) / BN_BITS2; + + // Expand |r| to the size of our modulus. + if (!bn_wexpand(r, num_words)) { + return 0; + } + + // Clear the upper words of |r|. + OPENSSL_memset(&r->d[r->width], 0, (num_words - r->width) * BN_BYTES); + + // Set parameters of |r|. + r->neg = 0; + r->width = (int)num_words; + + // Now, invert every word. The idea here is that we want to compute 2^e-|x|, + // which is actually equivalent to the twos-complement representation of |x| + // in |e| bits, which is -x = ~x + 1. + for (int i = 0; i < r->width; i++) { + r->d[i] = ~r->d[i]; + } + + // If our exponent doesn't span the top word, we have to mask the rest. + size_t top_word_exponent = e % BN_BITS2; + if (top_word_exponent != 0) { + r->d[r->width - 1] &= (((BN_ULONG)1) << top_word_exponent) - 1; + } + + // Keep the minimal-width invariant for |BIGNUM|. + bn_set_minimal_width(r); + + // Finally, add one, for the reason described above. + return BN_add(r, r, BN_value_one()); +}
diff --git a/crypto/bn/exponentiation.cc b/crypto/bn/exponentiation.cc index a6d7d9c..07f9ec6 100644 --- a/crypto/bn/exponentiation.cc +++ b/crypto/bn/exponentiation.cc
@@ -123,62 +123,44 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, const BN_MONT_CTX *mont) { - BIGNUM a_bignum; - BN_init(&a_bignum); - - int ret = 0; - // BN_mod_exp_mont requires reduced inputs. if (bn_minimal_width(m) == 1) { a %= m->d[0]; } - if (!BN_set_word(&a_bignum, a)) { + bssl::UniquePtr<BIGNUM> a_bignum(BN_new()); + if (a_bignum == nullptr || !BN_set_word(a_bignum.get(), a)) { OPENSSL_PUT_ERROR(BN, ERR_R_INTERNAL_ERROR); - goto err; + return 0; } - ret = BN_mod_exp_mont(rr, &a_bignum, p, m, ctx, mont); - -err: - BN_free(&a_bignum); - - return ret; + return BN_mod_exp_mont(rr, a_bignum.get(), p, m, ctx, mont); } int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1, const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m, BN_CTX *ctx, const BN_MONT_CTX *mont) { - BIGNUM tmp; - BN_init(&tmp); - - int ret = 0; - BN_MONT_CTX *new_mont = NULL; - // Allocate a montgomery context if it was not supplied by the caller. - if (mont == NULL) { - new_mont = BN_MONT_CTX_new_for_modulus(m, ctx); - if (new_mont == NULL) { - goto err; + bssl::UniquePtr<BN_MONT_CTX> new_mont; + if (mont == nullptr) { + new_mont.reset(BN_MONT_CTX_new_for_modulus(m, ctx)); + if (new_mont == nullptr) { + return 0; } - mont = new_mont; + mont = new_mont.get(); } // BN_mod_mul_montgomery removes one Montgomery factor, so passing one // Montgomery-encoded and one non-Montgomery-encoded value gives a // non-Montgomery-encoded result. - if (!BN_mod_exp_mont(rr, a1, p1, m, ctx, mont) || - !BN_mod_exp_mont(&tmp, a2, p2, m, ctx, mont) || + bssl::UniquePtr<BIGNUM> tmp(BN_new()); + if (tmp == nullptr || // + !BN_mod_exp_mont(rr, a1, p1, m, ctx, mont) || + !BN_mod_exp_mont(tmp.get(), a2, p2, m, ctx, mont) || !BN_to_montgomery(rr, rr, mont, ctx) || - !BN_mod_mul_montgomery(rr, rr, &tmp, mont, ctx)) { - goto err; + !BN_mod_mul_montgomery(rr, rr, tmp.get(), mont, ctx)) { + return 0; } - ret = 1; - -err: - BN_MONT_CTX_free(new_mont); - BN_free(&tmp); - - return ret; + return 1; }
diff --git a/crypto/bn/sqrt.cc b/crypto/bn/sqrt.cc new file mode 100644 index 0000000..e23f1a3 --- /dev/null +++ b/crypto/bn/sqrt.cc
@@ -0,0 +1,93 @@ +// Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. +// +// 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 +// +// https://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. + +#include <openssl/bn.h> + +#include <openssl/err.h> + + +int BN_sqrt(BIGNUM *out_sqrt, const BIGNUM *in, BN_CTX *ctx) { + BIGNUM *estimate, *tmp, *delta, *last_delta, *tmp2; + int ok = 0, last_delta_valid = 0; + + if (in->neg) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + if (BN_is_zero(in)) { + BN_zero(out_sqrt); + return 1; + } + + bssl::BN_CTXScope scope(ctx); + if (out_sqrt == in) { + estimate = BN_CTX_get(ctx); + } else { + estimate = out_sqrt; + } + tmp = BN_CTX_get(ctx); + last_delta = BN_CTX_get(ctx); + delta = BN_CTX_get(ctx); + if (estimate == NULL || tmp == NULL || last_delta == NULL || delta == NULL) { + goto err; + } + + // We estimate that the square root of an n-bit number is 2^{n/2}. + if (!BN_lshift(estimate, BN_value_one(), BN_num_bits(in)/2)) { + goto err; + } + + // This is Newton's method for finding a root of the equation |estimate|^2 - + // |in| = 0. + for (;;) { + // |estimate| = 1/2 * (|estimate| + |in|/|estimate|) + if (!BN_div(tmp, NULL, in, estimate, ctx) || + !BN_add(tmp, tmp, estimate) || + !BN_rshift1(estimate, tmp) || + // |tmp| = |estimate|^2 + !BN_sqr(tmp, estimate, ctx) || + // |delta| = |in| - |tmp| + !BN_sub(delta, in, tmp)) { + OPENSSL_PUT_ERROR(BN, ERR_R_BN_LIB); + goto err; + } + + delta->neg = 0; + // The difference between |in| and |estimate| squared is required to always + // decrease. This ensures that the loop always terminates, but I don't have + // a proof that it always finds the square root for a given square. + if (last_delta_valid && BN_cmp(delta, last_delta) >= 0) { + break; + } + + last_delta_valid = 1; + + tmp2 = last_delta; + last_delta = delta; + delta = tmp2; + } + + if (BN_cmp(tmp, in) != 0) { + OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE); + goto err; + } + + ok = 1; + +err: + if (ok && out_sqrt == in && !BN_copy(out_sqrt, estimate)) { + ok = 0; + } + return ok; +}
diff --git a/crypto/fipsmodule/bn/div.cc.inc b/crypto/fipsmodule/bn/div.cc.inc index 374e6e1..a29bf9c 100644 --- a/crypto/fipsmodule/bn/div.cc.inc +++ b/crypto/fipsmodule/bn/div.cc.inc
@@ -732,82 +732,3 @@ } return (BN_ULONG)ret; } - -int BN_mod_pow2(BIGNUM *r, const BIGNUM *a, size_t e) { - if (e == 0 || a->width == 0) { - BN_zero(r); - return 1; - } - - size_t num_words = 1 + ((e - 1) / BN_BITS2); - - // If |a| definitely has less than |e| bits, just BN_copy. - if ((size_t)a->width < num_words) { - return BN_copy(r, a) != NULL; - } - - // Otherwise, first make sure we have enough space in |r|. - // Note that this will fail if num_words > INT_MAX. - if (!bn_wexpand(r, num_words)) { - return 0; - } - - // Copy the content of |a| into |r|. - OPENSSL_memcpy(r->d, a->d, num_words * sizeof(BN_ULONG)); - - // If |e| isn't word-aligned, we have to mask off some of our bits. - size_t top_word_exponent = e % (sizeof(BN_ULONG) * 8); - if (top_word_exponent != 0) { - r->d[num_words - 1] &= (((BN_ULONG)1) << top_word_exponent) - 1; - } - - // Fill in the remaining fields of |r|. - r->neg = a->neg; - r->width = (int)num_words; - bn_set_minimal_width(r); - return 1; -} - -int BN_nnmod_pow2(BIGNUM *r, const BIGNUM *a, size_t e) { - if (!BN_mod_pow2(r, a, e)) { - return 0; - } - - // If the returned value was non-negative, we're done. - if (BN_is_zero(r) || !r->neg) { - return 1; - } - - size_t num_words = 1 + (e - 1) / BN_BITS2; - - // Expand |r| to the size of our modulus. - if (!bn_wexpand(r, num_words)) { - return 0; - } - - // Clear the upper words of |r|. - OPENSSL_memset(&r->d[r->width], 0, (num_words - r->width) * BN_BYTES); - - // Set parameters of |r|. - r->neg = 0; - r->width = (int)num_words; - - // Now, invert every word. The idea here is that we want to compute 2^e-|x|, - // which is actually equivalent to the twos-complement representation of |x| - // in |e| bits, which is -x = ~x + 1. - for (int i = 0; i < r->width; i++) { - r->d[i] = ~r->d[i]; - } - - // If our exponent doesn't span the top word, we have to mask the rest. - size_t top_word_exponent = e % BN_BITS2; - if (top_word_exponent != 0) { - r->d[r->width - 1] &= (((BN_ULONG)1) << top_word_exponent) - 1; - } - - // Keep the minimal-width invariant for |BIGNUM|. - bn_set_minimal_width(r); - - // Finally, add one, for the reason described above. - return BN_add(r, r, BN_value_one()); -}
diff --git a/crypto/fipsmodule/bn/exponentiation.cc.inc b/crypto/fipsmodule/bn/exponentiation.cc.inc index b719bea..205f4b4 100644 --- a/crypto/fipsmodule/bn/exponentiation.cc.inc +++ b/crypto/fipsmodule/bn/exponentiation.cc.inc
@@ -413,7 +413,6 @@ const BIGNUM *m, BN_CTX *ctx, const BN_MONT_CTX *mont) { int i, ret = 0, wvalue; - BN_MONT_CTX *new_mont = NULL; void *powerbuf_free = NULL; size_t powerbuf_len = 0; @@ -449,12 +448,13 @@ // Allocate a montgomery context if it was not supplied by the caller. int top, num_powers, window; - if (mont == NULL) { - new_mont = BN_MONT_CTX_new_consttime(m, ctx); - if (new_mont == NULL) { + bssl::UniquePtr<BN_MONT_CTX> new_mont; + if (mont == nullptr) { + new_mont.reset(BN_MONT_CTX_new_consttime(m, ctx)); + if (new_mont == nullptr) { goto err; } - mont = new_mont; + mont = new_mont.get(); } // Use the width in |mont->N|, rather than the copy in |m|. The assembly @@ -731,7 +731,6 @@ ret = 1; err: - BN_MONT_CTX_free(new_mont); if (powerbuf != NULL && powerbuf_free == NULL) { OPENSSL_cleanse(powerbuf, powerbuf_len); }
diff --git a/crypto/fipsmodule/bn/gcd.cc.inc b/crypto/fipsmodule/bn/gcd.cc.inc index 6e3cc06..e876c4d 100644 --- a/crypto/fipsmodule/bn/gcd.cc.inc +++ b/crypto/fipsmodule/bn/gcd.cc.inc
@@ -33,23 +33,20 @@ return 0; } - BIGNUM *A, *B, *X, *Y; - int ret = 0; int sign; - - BN_CTX_start(ctx); - A = BN_CTX_get(ctx); - B = BN_CTX_get(ctx); - X = BN_CTX_get(ctx); - Y = BN_CTX_get(ctx); + bssl::BN_CTXScope scope(ctx); + BIGNUM *A = BN_CTX_get(ctx); + BIGNUM *B = BN_CTX_get(ctx); + BIGNUM *X = BN_CTX_get(ctx); + BIGNUM *Y = BN_CTX_get(ctx); BIGNUM *R = out; if (Y == NULL) { - goto err; + return 0; } BN_zero(Y); if (!BN_one(X) || BN_copy(B, a) == NULL || BN_copy(A, n) == NULL) { - goto err; + return 0; } A->neg = 0; sign = -1; @@ -80,17 +77,17 @@ if (BN_is_odd(X)) { if (!BN_uadd(X, X, n)) { - goto err; + return 0; } } // now X is even, so we can easily divide it by two if (!BN_rshift1(X, X)) { - goto err; + return 0; } } if (shift > 0) { if (!BN_rshift(B, B, shift)) { - goto err; + return 0; } } @@ -102,17 +99,17 @@ if (BN_is_odd(Y)) { if (!BN_uadd(Y, Y, n)) { - goto err; + return 0; } } // now Y is even if (!BN_rshift1(Y, Y)) { - goto err; + return 0; } } if (shift > 0) { if (!BN_rshift(A, A, shift)) { - goto err; + return 0; } } @@ -129,21 +126,21 @@ if (BN_ucmp(B, A) >= 0) { // -sign*(X + Y)*a == B - A (mod |n|) if (!BN_uadd(X, X, Y)) { - goto err; + return 0; } // NB: we could use BN_mod_add_quick(X, X, Y, n), but that // actually makes the algorithm slower if (!BN_usub(B, B, A)) { - goto err; + return 0; } } else { // sign*(X + Y)*a == A - B (mod |n|) if (!BN_uadd(Y, Y, X)) { - goto err; + return 0; } // as above, BN_mod_add_quick(Y, Y, X, n) would slow things down if (!BN_usub(A, A, B)) { - goto err; + return 0; } } } @@ -151,7 +148,7 @@ if (!BN_is_one(A)) { *out_no_inverse = 1; OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE); - goto err; + return 0; } // The while loop (Euclid's algorithm) ends when @@ -162,7 +159,7 @@ if (sign < 0) { if (!BN_sub(Y, n, Y)) { - goto err; + return 0; } } // Now Y*a == A (mod |n|). @@ -170,61 +167,49 @@ // Y*a == 1 (mod |n|) if (Y->neg || BN_ucmp(Y, n) >= 0) { if (!BN_nnmod(Y, Y, n, ctx)) { - goto err; + return 0; } } if (!BN_copy(R, Y)) { - goto err; + return 0; } - ret = 1; - -err: - BN_CTX_end(ctx); - return ret; + return 1; } BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx) { - BIGNUM *new_out = NULL; - if (out == NULL) { - new_out = BN_new(); - if (new_out == NULL) { - return NULL; + bssl::UniquePtr<BIGNUM> new_out; + if (out == nullptr) { + new_out.reset(BN_new()); + if (new_out == nullptr) { + return nullptr; } - out = new_out; + out = new_out.get(); } - int ok = 0; - BIGNUM *a_reduced = NULL; + bssl::UniquePtr<BIGNUM> a_reduced; if (a->neg || BN_ucmp(a, n) >= 0) { - a_reduced = BN_dup(a); - if (a_reduced == NULL) { - goto err; + a_reduced.reset(BN_dup(a)); + if (a_reduced == nullptr) { + return nullptr; } - if (!BN_nnmod(a_reduced, a_reduced, n, ctx)) { - goto err; + if (!BN_nnmod(a_reduced.get(), a_reduced.get(), n, ctx)) { + return nullptr; } - a = a_reduced; + a = a_reduced.get(); } int no_inverse; if (!BN_is_odd(n)) { if (!bn_mod_inverse_consttime(out, &no_inverse, a, n, ctx)) { - goto err; + return nullptr; } } else if (!BN_mod_inverse_odd(out, &no_inverse, a, n, ctx)) { - goto err; + return nullptr; } - ok = 1; - -err: - if (!ok) { - BN_free(new_out); - out = NULL; - } - BN_free(a_reduced); + new_out.release(); // Passed to the caller via |out|. return out; } @@ -240,9 +225,10 @@ return 0; } - int ret = 0; - BIGNUM blinding_factor; - BN_init(&blinding_factor); + bssl::UniquePtr<BIGNUM> blinding_factor(BN_new()); + if (blinding_factor == nullptr) { + return 0; + } // |BN_mod_inverse_odd| is leaky, so generate a secret blinding factor and // blind |a|. This works because (ar)^-1 * r = a^-1, supposing r is @@ -253,12 +239,12 @@ // // TODO(crbug.com/boringssl/677): When the PRNG output is marked secret by // default, the explicit |bn_secret| call can be removed. - if (!BN_rand_range_ex(&blinding_factor, 1, &mont->N)) { - goto err; + if (!BN_rand_range_ex(blinding_factor.get(), 1, &mont->N)) { + return 0; } - bn_secret(&blinding_factor); - if (!BN_mod_mul_montgomery(out, &blinding_factor, a, mont, ctx)) { - goto err; + bn_secret(blinding_factor.get()); + if (!BN_mod_mul_montgomery(out, blinding_factor.get(), a, mont, ctx)) { + return 0; } // Once blinded, |out| is no longer secret, so it may be passed to a leaky @@ -266,35 +252,27 @@ // secret again after multiplying. bn_declassify(out); if (!BN_mod_inverse_odd(out, out_no_inverse, out, &mont->N, ctx) || - !BN_mod_mul_montgomery(out, &blinding_factor, out, mont, ctx)) { - goto err; + !BN_mod_mul_montgomery(out, blinding_factor.get(), out, mont, ctx)) { + return 0; } - ret = 1; - -err: - BN_free(&blinding_factor); - return ret; + return 1; } int bn_mod_inverse_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx, const BN_MONT_CTX *mont_p) { - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); BIGNUM *p_minus_2 = BN_CTX_get(ctx); - int ok = p_minus_2 != NULL && BN_copy(p_minus_2, p) && - BN_sub_word(p_minus_2, 2) && - BN_mod_exp_mont(out, a, p_minus_2, p, ctx, mont_p); - BN_CTX_end(ctx); - return ok; + return p_minus_2 != nullptr && BN_copy(p_minus_2, p) && + BN_sub_word(p_minus_2, 2) && + BN_mod_exp_mont(out, a, p_minus_2, p, ctx, mont_p); } int bn_mod_inverse_secret_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx, const BN_MONT_CTX *mont_p) { - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); BIGNUM *p_minus_2 = BN_CTX_get(ctx); - int ok = p_minus_2 != NULL && BN_copy(p_minus_2, p) && - BN_sub_word(p_minus_2, 2) && - BN_mod_exp_mont_consttime(out, a, p_minus_2, p, ctx, mont_p); - BN_CTX_end(ctx); - return ok; + return p_minus_2 != nullptr && BN_copy(p_minus_2, p) && + BN_sub_word(p_minus_2, 2) && + BN_mod_exp_mont_consttime(out, a, p_minus_2, p, ctx, mont_p); }
diff --git a/crypto/fipsmodule/bn/gcd_extra.cc.inc b/crypto/fipsmodule/bn/gcd_extra.cc.inc index d8642cd..dc0f072 100644 --- a/crypto/fipsmodule/bn/gcd_extra.cc.inc +++ b/crypto/fipsmodule/bn/gcd_extra.cc.inc
@@ -56,19 +56,18 @@ } // This is a constant-time implementation of Stein's algorithm (binary GCD). - int ret = 0; - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); BIGNUM *u = BN_CTX_get(ctx); BIGNUM *v = BN_CTX_get(ctx); BIGNUM *tmp = BN_CTX_get(ctx); unsigned x_bits, y_bits, num_iters, shift; - if (u == NULL || v == NULL || tmp == NULL || // + if (u == nullptr || v == nullptr || tmp == nullptr || // !BN_copy(u, x) || // !BN_copy(v, y) || // !bn_resize_words(u, width) || // !bn_resize_words(v, width) || // !bn_resize_words(tmp, width)) { - goto err; + return 0; } // Each loop iteration halves at least one of |u| and |v|. Thus we need at @@ -78,7 +77,7 @@ num_iters = x_bits + y_bits; if (num_iters < x_bits) { OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); - goto err; + return 0; } shift = 0; @@ -114,11 +113,7 @@ } *out_shift = shift; - ret = bn_set_words(r, v->d, width); - -err: - BN_CTX_end(ctx); - return ret; + return bn_set_words(r, v->d, width); } int BN_gcd(BIGNUM *r, const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) { @@ -128,12 +123,11 @@ int bn_is_relatively_prime(int *out_relatively_prime, const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) { - int ret = 0; - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); unsigned shift; BIGNUM *gcd = BN_CTX_get(ctx); - if (gcd == NULL || !bn_gcd_consttime(gcd, &shift, x, y, ctx)) { - goto err; + if (gcd == nullptr || !bn_gcd_consttime(gcd, &shift, x, y, ctx)) { + return 0; } // Check that 2^|shift| * |gcd| is one. @@ -146,25 +140,20 @@ } *out_relatively_prime = mask == 0; } - ret = 1; -err: - BN_CTX_end(ctx); - return ret; + return 1; } int bn_lcm_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); unsigned shift; BIGNUM *gcd = BN_CTX_get(ctx); - int ret = gcd != NULL && // - bn_mul_consttime(r, a, b, ctx) && - bn_gcd_consttime(gcd, &shift, a, b, ctx) && - // |gcd| has a secret bit width. - bn_div_consttime(r, NULL, r, gcd, /*divisor_min_bits=*/0, ctx) && - bn_rshift_secret_shift(r, r, shift, ctx); - BN_CTX_end(ctx); - return ret; + return gcd != nullptr && // + bn_mul_consttime(r, a, b, ctx) && + bn_gcd_consttime(gcd, &shift, a, b, ctx) && + // |gcd| has a secret bit width. + bn_div_consttime(r, nullptr, r, gcd, /*divisor_min_bits=*/0, ctx) && + bn_rshift_secret_shift(r, r, shift, ctx); } int bn_mod_inverse_consttime(BIGNUM *r, int *out_no_inverse, const BIGNUM *a, @@ -207,8 +196,7 @@ a_width = n_width; } - int ret = 0; - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); BIGNUM *u = BN_CTX_get(ctx); BIGNUM *v = BN_CTX_get(ctx); BIGNUM *A = BN_CTX_get(ctx); @@ -218,14 +206,14 @@ BIGNUM *tmp = BN_CTX_get(ctx); BIGNUM *tmp2 = BN_CTX_get(ctx); size_t a_bits, num_iters, n_bits; - if (u == NULL || // - v == NULL || // - A == NULL || // - B == NULL || // - C == NULL || // - D == NULL || // - tmp == NULL || // - tmp2 == NULL || // + if (u == nullptr || // + v == nullptr || // + A == nullptr || // + B == nullptr || // + C == nullptr || // + D == nullptr || // + tmp == nullptr || // + tmp2 == nullptr || // !BN_copy(u, a) || // !BN_copy(v, n) || // !BN_one(A) || // @@ -242,7 +230,7 @@ // |tmp| and |tmp2| may be used at either size. !bn_resize_words(tmp, n_width) || // !bn_resize_words(tmp2, n_width)) { - goto err; + return 0; } // Each loop iteration halves at least one of |u| and |v|. Thus we need at @@ -254,7 +242,7 @@ num_iters = a_bits + n_bits; if (num_iters < a_bits) { OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); - goto err; + return 0; } // Before and after each loop iteration, the following hold: @@ -328,12 +316,8 @@ if (constant_time_declassify_int(!BN_is_one(u))) { *out_no_inverse = 1; OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE); - goto err; + return 0; } - ret = BN_copy(r, A) != NULL; - -err: - BN_CTX_end(ctx); - return ret; + return BN_copy(r, A) != nullptr; }
diff --git a/crypto/fipsmodule/bn/jacobi.cc.inc b/crypto/fipsmodule/bn/jacobi.cc.inc index 0ac6f67..1c1c51f 100644 --- a/crypto/fipsmodule/bn/jacobi.cc.inc +++ b/crypto/fipsmodule/bn/jacobi.cc.inc
@@ -42,32 +42,29 @@ return -2; } - int ret = -2; - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); BIGNUM *A = BN_CTX_get(ctx); BIGNUM *B = BN_CTX_get(ctx); if (B == NULL) { - goto end; + return -2; } if (!BN_copy(A, a) || !BN_copy(B, b)) { - goto end; + return -2; } // Adapted from logic to compute the Kronecker symbol, originally implemented // according to Henri Cohen, "A Course in Computational Algebraic Number // Theory" (algorithm 1.4.10). - ret = 1; - + int ret = 1; while (1) { // Cohen's step 3: // B is positive and odd if (BN_is_zero(A)) { - ret = BN_is_one(B) ? ret : 0; - goto end; + return BN_is_one(B) ? ret : 0; } // now A is non-zero @@ -76,8 +73,7 @@ i++; } if (!BN_rshift(A, A, i)) { - ret = -2; - goto end; + return -2; } if (i & 1) { // i is odd @@ -93,16 +89,11 @@ // (A, B) := (B mod |A|, |A|) if (!BN_nnmod(B, B, A, ctx)) { - ret = -2; - goto end; + return -2; } BIGNUM *tmp = A; A = B; B = tmp; tmp->neg = 0; } - -end: - BN_CTX_end(ctx); - return ret; }
diff --git a/crypto/fipsmodule/bn/montgomery.cc.inc b/crypto/fipsmodule/bn/montgomery.cc.inc index c0adcca..4bafb11 100644 --- a/crypto/fipsmodule/bn/montgomery.cc.inc +++ b/crypto/fipsmodule/bn/montgomery.cc.inc
@@ -245,21 +245,13 @@ int BN_from_montgomery(BIGNUM *r, const BIGNUM *a, const BN_MONT_CTX *mont, BN_CTX *ctx) { - int ret = 0; - BIGNUM *t; - - BN_CTX_start(ctx); - t = BN_CTX_get(ctx); + bssl::BN_CTXScope scope(ctx); + BIGNUM *t = BN_CTX_get(ctx); if (t == NULL || !BN_copy(t, a)) { - goto err; + return 0; } - ret = BN_from_montgomery_word(r, t, mont); - -err: - BN_CTX_end(ctx); - - return ret; + return BN_from_montgomery_word(r, t, mont); } int bn_one_to_montgomery(BIGNUM *r, const BN_MONT_CTX *mont, BN_CTX *ctx) { @@ -286,34 +278,28 @@ const BIGNUM *b, const BN_MONT_CTX *mont, BN_CTX *ctx) { - int ret = 0; - - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); BIGNUM *tmp = BN_CTX_get(ctx); if (tmp == NULL) { - goto err; + return 0; } if (a == b) { if (!bn_sqr_consttime(tmp, a, ctx)) { - goto err; + return 0; } } else { if (!bn_mul_consttime(tmp, a, b, ctx)) { - goto err; + return 0; } } // reduce from aRR to aR if (!BN_from_montgomery_word(r, tmp, mont)) { - goto err; + return 0; } - ret = 1; - -err: - BN_CTX_end(ctx); - return ret; + return 1; } int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
diff --git a/crypto/fipsmodule/bn/mul.cc.inc b/crypto/fipsmodule/bn/mul.cc.inc index 4d7a919..9f75dde 100644 --- a/crypto/fipsmodule/bn/mul.cc.inc +++ b/crypto/fipsmodule/bn/mul.cc.inc
@@ -137,15 +137,14 @@ int cl = a->width < b->width ? a->width : b->width; int dl = a->width - b->width; int r_len = a->width < b->width ? b->width : a->width; - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); BIGNUM *tmp = BN_CTX_get(ctx); - int ok = tmp != NULL && bn_wexpand(r, r_len) && bn_wexpand(tmp, r_len); - if (ok) { - bn_abs_sub_part_words(r->d, a->d, b->d, cl, dl, tmp->d); - r->width = r_len; + if (tmp == nullptr || !bn_wexpand(r, r_len) || !bn_wexpand(tmp, r_len)) { + return 0; } - BN_CTX_end(ctx); - return ok; + bn_abs_sub_part_words(r->d, a->d, b->d, cl, dl, tmp->d); + r->width = r_len; + return 1; } // Karatsuba recursive multiplication algorithm @@ -377,13 +376,13 @@ return 1; } - int ret = 0, i, top; + int i, top; BIGNUM *rr; - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); if (r == a || r == b) { rr = BN_CTX_get(ctx); if (rr == NULL) { - goto err; + return 0; } } else { rr = r; @@ -394,7 +393,7 @@ if (i == 0) { if (al == 8) { if (!bn_wexpand(rr, 16)) { - goto err; + return 0; } rr->width = 16; bn_mul_comba8(rr->d, a->d, b->d); @@ -421,7 +420,7 @@ assert(j <= al || j <= bl); BIGNUM *t = BN_CTX_get(ctx); if (t == NULL) { - goto err; + return 0; } if (al > j || bl > j) { // We know |al| and |bl| are at most one from each other, so if al > j, @@ -432,7 +431,7 @@ // https://boringssl-review.googlesource.com/q/I0bd604e2cd6a75c266f64476c23a730ca1721ea6 assert(al >= j && bl >= j); if (!bn_wexpand(t, j * 8) || !bn_wexpand(rr, j * 4)) { - goto err; + return 0; } bn_mul_part_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d); } else { @@ -440,7 +439,7 @@ // of al - j or bl - j is zero. The other, by the bound on |i| above, is // zero or -1. Thus, we can use |bn_mul_recursive|. if (!bn_wexpand(t, j * 4) || !bn_wexpand(rr, j * 2)) { - goto err; + return 0; } bn_mul_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d); } @@ -450,20 +449,16 @@ } if (!bn_wexpand(rr, top)) { - goto err; + return 0; } rr->width = top; bn_mul_normal(rr->d, a->d, al, b->d, bl); end: if (r != rr && !BN_copy(r, rr)) { - goto err; + return 0; } - ret = 1; - -err: - BN_CTX_end(ctx); - return ret; + return 1; } int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { @@ -627,17 +622,16 @@ return 1; } - int ret = 0, max; - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); BIGNUM *rr = (a != r) ? r : BN_CTX_get(ctx); BIGNUM *tmp = BN_CTX_get(ctx); if (!rr || !tmp) { - goto err; + return 0; } - max = 2 * al; // Non-zero (from above) + int max = 2 * al; // Non-zero (from above) if (!bn_wexpand(rr, max)) { - goto err; + return 0; } if (al == 4) { @@ -658,12 +652,12 @@ // cryptographic primitives. if (al != 0 && (al & (al - 1)) == 0) { if (!bn_wexpand(tmp, al * 4)) { - goto err; + return 0; } bn_sqr_recursive(rr->d, a->d, al, tmp->d); } else { if (!bn_wexpand(tmp, max)) { - goto err; + return 0; } bn_sqr_normal(rr->d, a->d, al, tmp->d); } @@ -674,13 +668,9 @@ rr->width = max; if (rr != r && !BN_copy(r, rr)) { - goto err; + return 0; } - ret = 1; - -err: - BN_CTX_end(ctx); - return ret; + return 1; } int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) {
diff --git a/crypto/fipsmodule/bn/prime.cc.inc b/crypto/fipsmodule/bn/prime.cc.inc index 0471246..fabb545 100644 --- a/crypto/fipsmodule/bn/prime.cc.inc +++ b/crypto/fipsmodule/bn/prime.cc.inc
@@ -290,9 +290,7 @@ int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb) { BIGNUM *t; - int found = 0; int i, j, c1 = 0; - BN_CTX *ctx; int checks = BN_prime_checks_for_size(bits); if (bits < 2) { @@ -305,43 +303,43 @@ return 0; } - ctx = BN_CTX_new(); - if (ctx == NULL) { - goto err; + bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new()); + if (ctx == nullptr) { + return 0; } - BN_CTX_start(ctx); - t = BN_CTX_get(ctx); + bssl::BN_CTXScope scope(ctx.get()); + t = BN_CTX_get(ctx.get()); if (!t) { - goto err; + return 0; } loop: // make a random number and set the top and bottom bits if (add == NULL) { if (!probable_prime(ret, bits)) { - goto err; + return 0; } } else { if (safe) { - if (!probable_prime_dh_safe(ret, bits, add, rem, ctx)) { - goto err; + if (!probable_prime_dh_safe(ret, bits, add, rem, ctx.get())) { + return 0; } } else { - if (!probable_prime_dh(ret, bits, add, rem, ctx)) { - goto err; + if (!probable_prime_dh(ret, bits, add, rem, ctx.get())) { + return 0; } } } if (!BN_GENCB_call(cb, BN_GENCB_GENERATED, c1++)) { // aborted - goto err; + return 0; } if (!safe) { - i = BN_is_prime_fasttest_ex(ret, checks, ctx, 0, cb); + i = BN_is_prime_fasttest_ex(ret, checks, ctx.get(), 0, cb); if (i == -1) { - goto err; + return 0; } else if (i == 0) { goto loop; } @@ -349,7 +347,7 @@ // for "safe prime" generation, check that (p-1)/2 is prime. Since a prime // is odd, We just need to divide by 2 if (!BN_rshift1(t, ret)) { - goto err; + return 0; } // Interleave |ret| and |t|'s primality tests to avoid paying the full @@ -358,37 +356,29 @@ // TODO(davidben): This doesn't quite work because an iteration count of 1 // still runs the blinding mechanism. for (i = 0; i < checks; i++) { - j = BN_is_prime_fasttest_ex(ret, 1, ctx, 0, NULL); + j = BN_is_prime_fasttest_ex(ret, 1, ctx.get(), 0, NULL); if (j == -1) { - goto err; + return 0; } else if (j == 0) { goto loop; } - j = BN_is_prime_fasttest_ex(t, 1, ctx, 0, NULL); + j = BN_is_prime_fasttest_ex(t, 1, ctx.get(), 0, NULL); if (j == -1) { - goto err; + return 0; } else if (j == 0) { goto loop; } if (!BN_GENCB_call(cb, BN_GENCB_PRIME_TEST, i)) { - goto err; + return 0; } // We have a safe prime test pass } } // we have a prime :-) - found = 1; - -err: - if (ctx != NULL) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - - return found; + return 1; } static int bn_trial_division(uint16_t *out, const BIGNUM *bn) { @@ -453,8 +443,7 @@ int *out_is_possibly_prime, const BIGNUM *b, const BN_MONT_CTX *mont, BN_CTX *ctx) { // This function corresponds to steps 4.3 through 4.5 of FIPS 186-4, C.3.1. - int ret = 0; - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); // Step 4.3. We use Montgomery-encoding for better performance and to avoid // timing leaks. @@ -464,7 +453,7 @@ if (z == NULL || !BN_mod_exp_mont_consttime(z, b, miller_rabin->m, w, ctx, mont) || !BN_to_montgomery(z, z, mont, ctx)) { - goto err; + return 0; } // is_possibly_prime is all ones if we have determined |b| is not a composite @@ -493,7 +482,7 @@ // Step 4.5.1. if (!BN_mod_mul_montgomery(z, z, z, mont, ctx)) { - goto err; + return 0; } // Step 4.5.2. If z = w-1 and the loop is not done, this is not a composite @@ -513,11 +502,7 @@ } *out_is_possibly_prime = constant_time_declassify_w(is_possibly_prime) & 1; - ret = 1; - -err: - BN_CTX_end(ctx); - return ret; + return 1; } int BN_primality_test(int *out_is_probably_prime, const BIGNUM *w, int checks, @@ -598,26 +583,25 @@ checks = BN_prime_checks_for_size(BN_num_bits(w)); } - BN_CTX *new_ctx = NULL; - if (ctx == NULL) { - new_ctx = BN_CTX_new(); - if (new_ctx == NULL) { + bssl::UniquePtr<BN_CTX> new_ctx; + if (ctx == nullptr) { + new_ctx.reset(BN_CTX_new()); + if (new_ctx == nullptr) { return 0; } - ctx = new_ctx; + ctx = new_ctx.get(); } // See C.3.1 from FIPS 186-4. - int ret = 0; - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); BIGNUM *b = BN_CTX_get(ctx); - BN_MONT_CTX *mont = BN_MONT_CTX_new_consttime(w, ctx); + bssl::UniquePtr<BN_MONT_CTX> mont(BN_MONT_CTX_new_consttime(w, ctx)); BN_MILLER_RABIN miller_rabin; crypto_word_t uniform_iterations = 0; - if (b == NULL || mont == NULL || + if (b == nullptr || mont == nullptr || // Steps 1-3. - !bn_miller_rabin_init(&miller_rabin, mont, ctx)) { - goto err; + !bn_miller_rabin_init(&miller_rabin, mont.get(), ctx)) { + return 0; } // The following loop performs in inner iteration of the Miller-Rabin @@ -657,39 +641,32 @@ // Step 4.1-4.2 int is_uniform; if (!bn_rand_secret_range(b, &is_uniform, 2, miller_rabin.w1)) { - goto err; + return 0; } uniform_iterations += is_uniform; // Steps 4.3-4.5 int is_possibly_prime = 0; - if (!bn_miller_rabin_iteration(&miller_rabin, &is_possibly_prime, b, mont, - ctx)) { - goto err; + if (!bn_miller_rabin_iteration(&miller_rabin, &is_possibly_prime, b, + mont.get(), ctx)) { + return 0; } if (!is_possibly_prime) { // Step 4.6. We did not see z = w-1 before z = 1, so w must be composite. *out_is_probably_prime = 0; - ret = 1; - goto err; + return 1; } // Step 4.7 if (!BN_GENCB_call(cb, BN_GENCB_PRIME_TEST, i - 1)) { - goto err; + return 0; } } declassify_assert(uniform_iterations >= (crypto_word_t)checks); *out_is_probably_prime = 1; - ret = 1; - -err: - BN_MONT_CTX_free(mont); - BN_CTX_end(ctx); - BN_CTX_free(new_ctx); - return ret; + return 1; } int BN_is_prime_ex(const BIGNUM *candidate, int checks, BN_CTX *ctx, @@ -720,41 +697,36 @@ checks = BN_prime_checks_for_size(BN_num_bits(w)); } - int ret = 0; - BN_MONT_CTX *mont = NULL; - - BN_CTX_start(ctx); - + bssl::BN_CTXScope scope(ctx); BIGNUM *w1 = BN_CTX_get(ctx); - BIGNUM *b, *g, *z, *x, *x1, *m; - int a; - if (w1 == NULL || !BN_copy(w1, w) || !BN_sub_word(w1, 1)) { - goto err; + if (w1 == nullptr || !BN_copy(w1, w) || !BN_sub_word(w1, 1)) { + return 0; } // Write w1 as m*2^a (Steps 1 and 2). - a = 0; + int a = 0; while (!BN_is_bit_set(w1, a)) { a++; } - m = BN_CTX_get(ctx); - if (m == NULL || !BN_rshift(m, w1, a)) { - goto err; + BIGNUM *m = BN_CTX_get(ctx); + if (m == nullptr || !BN_rshift(m, w1, a)) { + return 0; } - b = BN_CTX_get(ctx); - g = BN_CTX_get(ctx); - z = BN_CTX_get(ctx); - x = BN_CTX_get(ctx); - x1 = BN_CTX_get(ctx); - if (b == NULL || g == NULL || z == NULL || x == NULL || x1 == NULL) { - goto err; + BIGNUM *b = BN_CTX_get(ctx); + BIGNUM *g = BN_CTX_get(ctx); + BIGNUM *z = BN_CTX_get(ctx); + BIGNUM *x = BN_CTX_get(ctx); + BIGNUM *x1 = BN_CTX_get(ctx); + if (b == nullptr || g == nullptr || z == nullptr || x == nullptr || + x1 == nullptr) { + return 0; } // Montgomery setup for computations mod w - mont = BN_MONT_CTX_new_for_modulus(w, ctx); - if (mont == NULL) { - goto err; + bssl::UniquePtr<BN_MONT_CTX> mont(BN_MONT_CTX_new_for_modulus(w, ctx)); + if (mont == nullptr) { + return 0; } // The following loop performs in inner iteration of the Enhanced Miller-Rabin @@ -762,22 +734,21 @@ for (int i = 1; i <= checks; i++) { // Step 4.1-4.2 if (!BN_rand_range_ex(b, 2, w1)) { - goto err; + return 0; } // Step 4.3-4.4 if (!BN_gcd(g, b, w, ctx)) { - goto err; + return 0; } if (BN_cmp_word(g, 1) > 0) { *out_result = bn_composite; - ret = 1; - goto err; + return 1; } // Step 4.5 - if (!BN_mod_exp_mont(z, b, m, w, ctx, mont)) { - goto err; + if (!BN_mod_exp_mont(z, b, m, w, ctx, mont.get())) { + return 0; } // Step 4.6 @@ -788,7 +759,7 @@ // Step 4.7 for (int j = 1; j < a; j++) { if (!BN_copy(x, z) || !BN_mod_mul(z, x, x, w, ctx)) { - goto err; + return 0; } if (BN_cmp(z, w1) == 0) { goto loop; @@ -800,18 +771,18 @@ // Step 4.8-4.9 if (!BN_copy(x, z) || !BN_mod_mul(z, x, x, w, ctx)) { - goto err; + return 0; } // Step 4.10-4.11 if (!BN_is_one(z) && !BN_copy(x, z)) { - goto err; + return 0; } composite: // Step 4.12-4.14 if (!BN_copy(x1, x) || !BN_sub_word(x1, 1) || !BN_gcd(g, x1, w, ctx)) { - goto err; + return 0; } if (BN_cmp_word(g, 1) > 0) { *out_result = bn_composite; @@ -819,24 +790,17 @@ *out_result = bn_non_prime_power_composite; } - ret = 1; - goto err; + return 1; loop: // Step 4.15 if (!BN_GENCB_call(cb, BN_GENCB_PRIME_TEST, i - 1)) { - goto err; + return 0; } } *out_result = bn_probably_prime; - ret = 1; - -err: - BN_MONT_CTX_free(mont); - BN_CTX_end(ctx); - - return ret; + return 1; } static int probable_prime(BIGNUM *rnd, int bits) { @@ -850,111 +814,99 @@ static int probable_prime_dh(BIGNUM *rnd, int bits, const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx) { - int ret = 0; + bssl::BN_CTXScope scope(ctx); BIGNUM *t1; - - BN_CTX_start(ctx); - size_t num_primes; - if ((t1 = BN_CTX_get(ctx)) == NULL) { - goto err; + if ((t1 = BN_CTX_get(ctx)) == nullptr) { + return 0; } if (!BN_rand(rnd, bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD)) { - goto err; + return 0; } // we need ((rnd-rem) % add) == 0 - if (!BN_mod(t1, rnd, add, ctx)) { - goto err; + return 0; } if (!BN_sub(rnd, rnd, t1)) { - goto err; + return 0; } - if (rem == NULL) { + if (rem == nullptr) { if (!BN_add_word(rnd, 1)) { - goto err; + return 0; } } else { if (!BN_add(rnd, rnd, rem)) { - goto err; + return 0; } } // we now have a random number 'rand' to test. - num_primes = num_trial_division_primes(rnd); + size_t num_primes = num_trial_division_primes(rnd); loop: for (size_t i = 1; i < num_primes; i++) { // check that rnd is a prime if (bn_mod_u16_consttime(rnd, kPrimes[i]) <= 1) { if (!BN_add(rnd, rnd, add)) { - goto err; + return 0; } goto loop; } } - ret = 1; - -err: - BN_CTX_end(ctx); - return ret; + return 1; } static int probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd, const BIGNUM *rem, BN_CTX *ctx) { - int ret = 0; - BIGNUM *t1, *qadd, *q; - bits--; - BN_CTX_start(ctx); - t1 = BN_CTX_get(ctx); - q = BN_CTX_get(ctx); - qadd = BN_CTX_get(ctx); - size_t num_primes; + bssl::BN_CTXScope scope(ctx); + BIGNUM *t1 = BN_CTX_get(ctx); + BIGNUM *q = BN_CTX_get(ctx); + BIGNUM *qadd = BN_CTX_get(ctx); if (qadd == NULL) { - goto err; + return 0; } if (!BN_rshift1(qadd, padd)) { - goto err; + return 0; } if (!BN_rand(q, bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD)) { - goto err; + return 0; } // we need ((rnd-rem) % add) == 0 if (!BN_mod(t1, q, qadd, ctx)) { - goto err; + return 0; } if (!BN_sub(q, q, t1)) { - goto err; + return 0; } if (rem == NULL) { if (!BN_add_word(q, 1)) { - goto err; + return 0; } } else { if (!BN_rshift1(t1, rem)) { - goto err; + return 0; } if (!BN_add(q, q, t1)) { - goto err; + return 0; } } // we now have a random number 'rand' to test. if (!BN_lshift1(p, q)) { - goto err; + return 0; } if (!BN_add_word(p, 1)) { - goto err; + return 0; } - num_primes = num_trial_division_primes(p); + size_t num_primes = num_trial_division_primes(p); loop: for (size_t i = 1; i < num_primes; i++) { // check that p and q are prime @@ -963,18 +915,14 @@ if (bn_mod_u16_consttime(p, kPrimes[i]) == 0 || bn_mod_u16_consttime(q, kPrimes[i]) == 0) { if (!BN_add(p, p, padd)) { - goto err; + return 0; } if (!BN_add(q, q, qadd)) { - goto err; + return 0; } goto loop; } } - ret = 1; - -err: - BN_CTX_end(ctx); - return ret; + return 1; }
diff --git a/crypto/fipsmodule/bn/shift.cc.inc b/crypto/fipsmodule/bn/shift.cc.inc index 2739c5a..491c796 100644 --- a/crypto/fipsmodule/bn/shift.cc.inc +++ b/crypto/fipsmodule/bn/shift.cc.inc
@@ -129,12 +129,11 @@ int bn_rshift_secret_shift(BIGNUM *r, const BIGNUM *a, unsigned n, BN_CTX *ctx) { - int ret = 0; - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); BIGNUM *tmp = BN_CTX_get(ctx); unsigned max_bits; if (tmp == NULL || !BN_copy(r, a) || !bn_wexpand(tmp, r->width)) { - goto err; + return 0; } // Shift conditionally by powers of two. @@ -147,11 +146,7 @@ r->d /* ignore shift */, r->width); } - ret = 1; - -err: - BN_CTX_end(ctx); - return ret; + return 1; } void bn_rshift1_words(BN_ULONG *r, const BN_ULONG *a, size_t num) {
diff --git a/crypto/fipsmodule/bn/sqrt.cc.inc b/crypto/fipsmodule/bn/sqrt.cc.inc index cb70f19..56d89e0 100644 --- a/crypto/fipsmodule/bn/sqrt.cc.inc +++ b/crypto/fipsmodule/bn/sqrt.cc.inc
@@ -63,7 +63,7 @@ return ret; } - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); A = BN_CTX_get(ctx); b = BN_CTX_get(ctx); q = BN_CTX_get(ctx); @@ -378,82 +378,5 @@ } ret = NULL; } - BN_CTX_end(ctx); return ret; } - -int BN_sqrt(BIGNUM *out_sqrt, const BIGNUM *in, BN_CTX *ctx) { - BIGNUM *estimate, *tmp, *delta, *last_delta, *tmp2; - int ok = 0, last_delta_valid = 0; - - if (in->neg) { - OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); - return 0; - } - if (BN_is_zero(in)) { - BN_zero(out_sqrt); - return 1; - } - - BN_CTX_start(ctx); - if (out_sqrt == in) { - estimate = BN_CTX_get(ctx); - } else { - estimate = out_sqrt; - } - tmp = BN_CTX_get(ctx); - last_delta = BN_CTX_get(ctx); - delta = BN_CTX_get(ctx); - if (estimate == NULL || tmp == NULL || last_delta == NULL || delta == NULL) { - goto err; - } - - // We estimate that the square root of an n-bit number is 2^{n/2}. - if (!BN_lshift(estimate, BN_value_one(), BN_num_bits(in)/2)) { - goto err; - } - - // This is Newton's method for finding a root of the equation |estimate|^2 - - // |in| = 0. - for (;;) { - // |estimate| = 1/2 * (|estimate| + |in|/|estimate|) - if (!BN_div(tmp, NULL, in, estimate, ctx) || - !BN_add(tmp, tmp, estimate) || - !BN_rshift1(estimate, tmp) || - // |tmp| = |estimate|^2 - !BN_sqr(tmp, estimate, ctx) || - // |delta| = |in| - |tmp| - !BN_sub(delta, in, tmp)) { - OPENSSL_PUT_ERROR(BN, ERR_R_BN_LIB); - goto err; - } - - delta->neg = 0; - // The difference between |in| and |estimate| squared is required to always - // decrease. This ensures that the loop always terminates, but I don't have - // a proof that it always finds the square root for a given square. - if (last_delta_valid && BN_cmp(delta, last_delta) >= 0) { - break; - } - - last_delta_valid = 1; - - tmp2 = last_delta; - last_delta = delta; - delta = tmp2; - } - - if (BN_cmp(tmp, in) != 0) { - OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE); - goto err; - } - - ok = 1; - -err: - if (ok && out_sqrt == in && !BN_copy(out_sqrt, estimate)) { - ok = 0; - } - BN_CTX_end(ctx); - return ok; -}
diff --git a/crypto/fipsmodule/dh/check.cc.inc b/crypto/fipsmodule/dh/check.cc.inc index c15b858..4d023d5 100644 --- a/crypto/fipsmodule/dh/check.cc.inc +++ b/crypto/fipsmodule/dh/check.cc.inc
@@ -55,13 +55,11 @@ return 0; } - BN_CTX *ctx = BN_CTX_new(); + bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new()); if (ctx == NULL) { return 0; } - BN_CTX_start(ctx); - - int ok = 0; + bssl::BN_CTXScope scope(ctx.get()); // Check |pub_key| is greater than 1. if (BN_cmp(pub_key, BN_value_one()) <= 0) { @@ -69,11 +67,11 @@ } // Check |pub_key| is less than |dh->p| - 1. - BIGNUM *tmp = BN_CTX_get(ctx); + BIGNUM *tmp = BN_CTX_get(ctx.get()); if (tmp == NULL || !BN_copy(tmp, dh->p) || !BN_sub_word(tmp, 1)) { - goto err; + return 0; } if (BN_cmp(pub_key, tmp) >= 0) { *out_flags |= DH_CHECK_PUBKEY_TOO_LARGE; @@ -83,23 +81,17 @@ // Check |pub_key|^|dh->q| is 1 mod |dh->p|. This is necessary for RFC 5114 // groups which are not safe primes but pick a generator on a prime-order // subgroup of size |dh->q|. - if (!BN_mod_exp_mont(tmp, pub_key, dh->q, dh->p, ctx, NULL)) { - goto err; + if (!BN_mod_exp_mont(tmp, pub_key, dh->q, dh->p, ctx.get(), NULL)) { + return 0; } if (!BN_is_one(tmp)) { *out_flags |= DH_CHECK_PUBKEY_INVALID; } } - ok = 1; - -err: - BN_CTX_end(ctx); - BN_CTX_free(ctx); - return ok; + return 1; } - int DH_check(const DH *dh, int *out_flags) { *out_flags = 0; if (!dh_check_params_fast(dh)) { @@ -112,23 +104,18 @@ // for 3, p mod 12 == 5 // for 5, p mod 10 == 3 or 7 // should hold. - int ok = 0, r; - BN_CTX *ctx = NULL; - BN_ULONG l; - BIGNUM *t1 = NULL, *t2 = NULL; - - ctx = BN_CTX_new(); - if (ctx == NULL) { - goto err; + bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new()); + if (ctx == nullptr) { + return 0; } - BN_CTX_start(ctx); - t1 = BN_CTX_get(ctx); - if (t1 == NULL) { - goto err; + bssl::BN_CTXScope scope(ctx.get()); + BIGNUM *t1 = BN_CTX_get(ctx.get()); + if (t1 == nullptr) { + return 0; } - t2 = BN_CTX_get(ctx); - if (t2 == NULL) { - goto err; + BIGNUM *t2 = BN_CTX_get(ctx.get()); + if (t2 == nullptr) { + return 0; } if (dh->q) { @@ -138,39 +125,40 @@ *out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR; } else { // Check g^q == 1 mod p - if (!BN_mod_exp_mont(t1, dh->g, dh->q, dh->p, ctx, NULL)) { - goto err; + if (!BN_mod_exp_mont(t1, dh->g, dh->q, dh->p, ctx.get(), nullptr)) { + return 0; } if (!BN_is_one(t1)) { *out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR; } } - r = BN_is_prime_ex(dh->q, BN_prime_checks_for_validation, ctx, NULL); + int r = BN_is_prime_ex(dh->q, BN_prime_checks_for_validation, ctx.get(), + nullptr); if (r < 0) { - goto err; + return 0; } if (!r) { *out_flags |= DH_CHECK_Q_NOT_PRIME; } // Check p == 1 mod q i.e. q divides p - 1 - if (!BN_div(t1, t2, dh->p, dh->q, ctx)) { - goto err; + if (!BN_div(t1, t2, dh->p, dh->q, ctx.get())) { + return 0; } if (!BN_is_one(t2)) { *out_flags |= DH_CHECK_INVALID_Q_VALUE; } } else if (BN_is_word(dh->g, DH_GENERATOR_2)) { - l = BN_mod_word(dh->p, 24); + BN_ULONG l = BN_mod_word(dh->p, 24); if (l == (BN_ULONG)-1) { - goto err; + return 0; } if (l != 11) { *out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR; } } else if (BN_is_word(dh->g, DH_GENERATOR_5)) { - l = BN_mod_word(dh->p, 10); + BN_ULONG l = BN_mod_word(dh->p, 10); if (l == (BN_ULONG)-1) { - goto err; + return 0; } if (l != 3 && l != 7) { *out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR; @@ -179,30 +167,24 @@ *out_flags |= DH_CHECK_UNABLE_TO_CHECK_GENERATOR; } - r = BN_is_prime_ex(dh->p, BN_prime_checks_for_validation, ctx, NULL); + int r = + BN_is_prime_ex(dh->p, BN_prime_checks_for_validation, ctx.get(), nullptr); if (r < 0) { - goto err; + return 0; } if (!r) { *out_flags |= DH_CHECK_P_NOT_PRIME; } else if (!dh->q) { if (!BN_rshift1(t1, dh->p)) { - goto err; + return 0; } - r = BN_is_prime_ex(t1, BN_prime_checks_for_validation, ctx, NULL); + r = BN_is_prime_ex(t1, BN_prime_checks_for_validation, ctx.get(), nullptr); if (r < 0) { - goto err; + return 0; } if (!r) { *out_flags |= DH_CHECK_P_NOT_SAFE_PRIME; } } - ok = 1; - -err: - if (ctx != NULL) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - return ok; + return 1; }
diff --git a/crypto/fipsmodule/dh/dh.cc.inc b/crypto/fipsmodule/dh/dh.cc.inc index 6f1267f..0a62215 100644 --- a/crypto/fipsmodule/dh/dh.cc.inc +++ b/crypto/fipsmodule/dh/dh.cc.inc
@@ -147,28 +147,27 @@ } int ok = 0; - int generate_new_key = 0; - BN_CTX *ctx = NULL; - BIGNUM *pub_key = NULL, *priv_key = NULL, *priv_key_limit = NULL; + bool generate_new_key = false; + BIGNUM *pub_key = nullptr, *priv_key = nullptr; - ctx = BN_CTX_new(); - if (ctx == NULL) { + bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new()); + if (ctx == nullptr) { goto err; } - if (dh->priv_key == NULL) { + if (dh->priv_key == nullptr) { priv_key = BN_new(); - if (priv_key == NULL) { + if (priv_key == nullptr) { goto err; } - generate_new_key = 1; + generate_new_key = true; } else { priv_key = dh->priv_key; } - if (dh->pub_key == NULL) { + if (dh->pub_key == nullptr) { pub_key = BN_new(); - if (pub_key == NULL) { + if (pub_key == nullptr) { goto err; } } else { @@ -176,7 +175,7 @@ } if (!BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock, - dh->p, ctx)) { + dh->p, ctx.get())) { goto err; } @@ -202,30 +201,30 @@ // clamp |dh->priv_length| before invoking the algorithm. // Compute M = min(2^N, q). - priv_key_limit = BN_new(); - if (priv_key_limit == NULL) { + bssl::UniquePtr<BIGNUM> priv_key_limit(BN_new()); + if (priv_key_limit == nullptr) { goto err; } if (dh->priv_length == 0 || dh->priv_length >= BN_num_bits(dh->p) - 1) { // M = q = (p - 1) / 2. - if (!BN_rshift1(priv_key_limit, dh->p)) { + if (!BN_rshift1(priv_key_limit.get(), dh->p)) { goto err; } } else { // M = 2^N. - if (!BN_set_bit(priv_key_limit, dh->priv_length)) { + if (!BN_set_bit(priv_key_limit.get(), dh->priv_length)) { goto err; } } // Choose a private key uniformly from [1, M-1]. - if (!BN_rand_range_ex(priv_key, 1, priv_key_limit)) { + if (!BN_rand_range_ex(priv_key, 1, priv_key_limit.get())) { goto err; } } } - if (!BN_mod_exp_mont_consttime(pub_key, dh->g, priv_key, dh->p, ctx, + if (!BN_mod_exp_mont_consttime(pub_key, dh->g, priv_key, dh->p, ctx.get(), dh->method_mont_p)) { goto err; } @@ -239,14 +238,12 @@ OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB); } - if (dh->pub_key == NULL) { + if (dh->pub_key == nullptr) { BN_free(pub_key); } - if (dh->priv_key == NULL) { + if (dh->priv_key == nullptr) { BN_free(priv_key); } - BN_free(priv_key_limit); - BN_CTX_free(ctx); return ok; } @@ -267,56 +264,46 @@ return 0; } - int ret = 0; - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); BIGNUM *p_minus_1 = BN_CTX_get(ctx); - if (!p_minus_1 || !BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock, dh->p, ctx)) { - goto err; + return 0; } if (!BN_mod_exp_mont_consttime(out_shared_key, peers_key, dh->priv_key, dh->p, ctx, dh->method_mont_p) || !BN_copy(p_minus_1, dh->p) || !BN_sub_word(p_minus_1, 1)) { OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB); - goto err; + return 0; } // This performs the check required by SP 800-56Ar3 section 5.7.1.1 step two. if (BN_cmp_word(out_shared_key, 1) <= 0 || BN_cmp(out_shared_key, p_minus_1) == 0) { OPENSSL_PUT_ERROR(DH, DH_R_INVALID_PUBKEY); - goto err; + return 0; } - ret = 1; - -err: - BN_CTX_end(ctx); - return ret; + return 1; } int dh_compute_key_padded_no_self_test(unsigned char *out, const BIGNUM *peers_key, DH *dh) { - BN_CTX *ctx = BN_CTX_new(); - if (ctx == NULL) { + bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new()); + if (ctx == nullptr) { return -1; } - BN_CTX_start(ctx); - + bssl::BN_CTXScope scope(ctx.get()); int dh_size = DH_size(dh); - int ret = -1; - BIGNUM *shared_key = BN_CTX_get(ctx); - if (shared_key && dh_compute_key(dh, shared_key, peers_key, ctx) && - BN_bn2bin_padded(out, dh_size, shared_key)) { - ret = dh_size; + BIGNUM *shared_key = BN_CTX_get(ctx.get()); + if (shared_key == nullptr || + !dh_compute_key(dh, shared_key, peers_key, ctx.get()) || + !BN_bn2bin_padded(out, dh_size, shared_key)) { + return -1; } - - BN_CTX_end(ctx); - BN_CTX_free(ctx); - return ret; + return dh_size; } int DH_compute_key_padded(unsigned char *out, const BIGNUM *peers_key, DH *dh) { @@ -328,22 +315,18 @@ int DH_compute_key(unsigned char *out, const BIGNUM *peers_key, DH *dh) { boringssl_ensure_ffdh_self_test(); - BN_CTX *ctx = BN_CTX_new(); - if (ctx == NULL) { + bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new()); + if (ctx == nullptr) { return -1; } - BN_CTX_start(ctx); - - int ret = -1; - BIGNUM *shared_key = BN_CTX_get(ctx); - if (shared_key && dh_compute_key(dh, shared_key, peers_key, ctx)) { - // A |BIGNUM|'s byte count fits in |int|. - ret = (int)BN_bn2bin(shared_key, out); + bssl::BN_CTXScope scope(ctx.get()); + BIGNUM *shared_key = BN_CTX_get(ctx.get()); + if (shared_key == nullptr || + !dh_compute_key(dh, shared_key, peers_key, ctx.get())) { + return -1; } - - BN_CTX_end(ctx); - BN_CTX_free(ctx); - return ret; + // A |BIGNUM|'s byte count fits in |int|. + return static_cast<int>(BN_bn2bin(shared_key, out)); } int DH_compute_key_hashed(DH *dh, uint8_t *out, size_t *out_len, @@ -415,29 +398,27 @@ TOBN(0xadf85458, 0xa2bb4a9a), TOBN(0xffffffff, 0xffffffff), }; - BIGNUM *const ffdhe2048_p = BN_new(); - BIGNUM *const ffdhe2048_q = BN_new(); - BIGNUM *const ffdhe2048_g = BN_new(); - DH *const dh = DH_new(); - + bssl::UniquePtr<BIGNUM> ffdhe2048_p(BN_new()); + bssl::UniquePtr<BIGNUM> ffdhe2048_q(BN_new()); + bssl::UniquePtr<BIGNUM> ffdhe2048_g(BN_new()); + bssl::UniquePtr<DH> dh(DH_new()); if (!ffdhe2048_p || !ffdhe2048_q || !ffdhe2048_g || !dh) { - goto err; + return nullptr; } - bn_set_static_words(ffdhe2048_p, kFFDHE2048Data, + bn_set_static_words(ffdhe2048_p.get(), kFFDHE2048Data, OPENSSL_ARRAY_SIZE(kFFDHE2048Data)); - if (!BN_rshift1(ffdhe2048_q, ffdhe2048_p) || !BN_set_word(ffdhe2048_g, 2) || - !DH_set0_pqg(dh, ffdhe2048_p, ffdhe2048_q, ffdhe2048_g)) { - goto err; + if (!BN_rshift1(ffdhe2048_q.get(), ffdhe2048_p.get()) || + !BN_set_word(ffdhe2048_g.get(), 2) || + !DH_set0_pqg(dh.get(), ffdhe2048_p.get(), ffdhe2048_q.get(), + ffdhe2048_g.get())) { + return nullptr; } + // |DH_set0_pqg| takes ownership on success. + ffdhe2048_p.release(); + ffdhe2048_q.release(); + ffdhe2048_g.release(); - return dh; - -err: - BN_free(ffdhe2048_p); - BN_free(ffdhe2048_q); - BN_free(ffdhe2048_g); - DH_free(dh); - return NULL; + return dh.release(); }
diff --git a/crypto/fipsmodule/ec/ec.cc.inc b/crypto/fipsmodule/ec/ec.cc.inc index f1409d9..14916ee 100644 --- a/crypto/fipsmodule/ec/ec.cc.inc +++ b/crypto/fipsmodule/ec/ec.cc.inc
@@ -655,12 +655,10 @@ ERR_clear_error(); // This is an unusual input, so we do not guarantee constant-time processing. - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); BIGNUM *tmp = BN_CTX_get(ctx); - int ok = tmp != NULL && BN_nnmod(tmp, in, EC_GROUP_get0_order(group), ctx) && - ec_bignum_to_scalar(group, out, tmp); - BN_CTX_end(ctx); - return ok; + return tmp != nullptr && BN_nnmod(tmp, in, EC_GROUP_get0_order(group), ctx) && + ec_bignum_to_scalar(group, out, tmp); } int ec_point_mul_no_self_test(const EC_GROUP *group, EC_POINT *r,
diff --git a/crypto/fipsmodule/rsa/rsa.cc.inc b/crypto/fipsmodule/rsa/rsa.cc.inc index 0240e8a..ebcd558 100644 --- a/crypto/fipsmodule/rsa/rsa.cc.inc +++ b/crypto/fipsmodule/rsa/rsa.cc.inc
@@ -718,15 +718,15 @@ // Note |bn_mul_consttime| and |bn_div_consttime| do not scale linearly, but // checking |ainv| is in range bounds the running time, assuming |m|'s bounds // were checked by the caller. - BN_CTX_start(ctx); + bssl::BN_CTXScope scope(ctx); BIGNUM *tmp = BN_CTX_get(ctx); - int ret = tmp != NULL && bn_mul_consttime(tmp, a, ainv, ctx) && - bn_div_consttime(NULL, tmp, tmp, m, m_min_bits, ctx); - if (ret) { - *out_ok = constant_time_declassify_int(BN_is_one(tmp)); + if (tmp == nullptr || // + !bn_mul_consttime(tmp, a, ainv, ctx) || + !bn_div_consttime(NULL, tmp, tmp, m, m_min_bits, ctx)) { + return 0; } - BN_CTX_end(ctx); - return ret; + *out_ok = constant_time_declassify_int(BN_is_one(tmp)); + return 1; } int RSA_check_key(const RSA *key) {
diff --git a/crypto/fipsmodule/rsa/rsa_impl.cc.inc b/crypto/fipsmodule/rsa/rsa_impl.cc.inc index 5aad8e9..e5c34f1 100644 --- a/crypto/fipsmodule/rsa/rsa_impl.cc.inc +++ b/crypto/fipsmodule/rsa/rsa_impl.cc.inc
@@ -446,8 +446,6 @@ } const unsigned rsa_size = RSA_size(rsa); - BIGNUM *f, *result; - if (max_out < rsa_size) { OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL); return 0; @@ -458,18 +456,17 @@ return 0; } - BN_CTX *ctx = BN_CTX_new(); - if (ctx == NULL) { + bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new()); + if (ctx == nullptr) { return 0; } int ret = 0; - uint8_t *buf = NULL; - - BN_CTX_start(ctx); - f = BN_CTX_get(ctx); - result = BN_CTX_get(ctx); - if (f == NULL || result == NULL) { + uint8_t *buf = nullptr; + bssl::BN_CTXScope scope(ctx.get()); + BIGNUM *f = BN_CTX_get(ctx.get()); + BIGNUM *result = BN_CTX_get(ctx.get()); + if (f == nullptr || result == nullptr) { goto err; } @@ -478,12 +475,12 @@ } else { // Allocate a temporary buffer to hold the padded plaintext. buf = reinterpret_cast<uint8_t *>(OPENSSL_malloc(rsa_size)); - if (buf == NULL) { + if (buf == nullptr) { goto err; } } - if (BN_bin2bn(in, in_len, f) == NULL) { + if (BN_bin2bn(in, in_len, f) == nullptr) { goto err; } @@ -492,8 +489,9 @@ goto err; } - if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) || - !BN_mod_exp_mont(result, f, rsa->e, &rsa->mont_n->N, ctx, rsa->mont_n)) { + if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx.get()) || + !BN_mod_exp_mont(result, f, rsa->e, &rsa->mont_n->N, ctx.get(), + rsa->mont_n)) { goto err; } @@ -522,8 +520,6 @@ } err: - BN_CTX_end(ctx); - BN_CTX_free(ctx); if (buf != out) { OPENSSL_free(buf); } @@ -539,32 +535,28 @@ int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, size_t len) { - if (rsa->n == NULL || rsa->d == NULL) { + if (rsa->n == nullptr || rsa->d == nullptr) { OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); return 0; } - BIGNUM *f, *result; - BN_CTX *ctx = NULL; - size_t blinding_index = 0; - BN_BLINDING *blinding = NULL; - int ret = 0, do_blinding; - - ctx = BN_CTX_new(); - if (ctx == NULL) { - goto err; + bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new()); + if (ctx == nullptr) { + return 0; } - BN_CTX_start(ctx); - f = BN_CTX_get(ctx); - result = BN_CTX_get(ctx); - - if (f == NULL || result == NULL) { + size_t blinding_index = 0; + BN_BLINDING *blinding = nullptr; + int ret = 0, do_blinding; + bssl::BN_CTXScope scope(ctx.get()); + BIGNUM *f = BN_CTX_get(ctx.get()); + BIGNUM *result = BN_CTX_get(ctx.get()); + if (f == nullptr || result == nullptr) { goto err; } // The caller should have ensured this. assert(len == BN_num_bytes(rsa->n)); - if (BN_bin2bn(in, len, f) == NULL) { + if (BN_bin2bn(in, len, f) == nullptr) { goto err; } @@ -576,7 +568,7 @@ goto err; } - if (!freeze_private_key(rsa, ctx)) { + if (!freeze_private_key(rsa, ctx.get())) { OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); goto err; } @@ -584,7 +576,7 @@ do_blinding = (rsa->flags & (RSA_FLAG_NO_BLINDING | RSA_FLAG_NO_PUBLIC_EXPONENT)) == 0; - if (rsa->e == NULL && do_blinding) { + if (rsa->e == nullptr && do_blinding) { // We cannot do blinding or verification without |e|, and continuing without // those countermeasures is dangerous. However, the Java/Android RSA API // requires support for keys where only |d| and |n| (and not |e|) are known. @@ -598,29 +590,29 @@ } if (do_blinding) { - blinding = rsa_blinding_get(rsa, &blinding_index, ctx); - if (blinding == NULL) { + blinding = rsa_blinding_get(rsa, &blinding_index, ctx.get()); + if (blinding == nullptr) { OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); goto err; } - if (!BN_BLINDING_convert(f, blinding, rsa->e, rsa->mont_n, ctx)) { + if (!BN_BLINDING_convert(f, blinding, rsa->e, rsa->mont_n, ctx.get())) { goto err; } } - if (rsa->p != NULL && rsa->q != NULL && rsa->e != NULL && rsa->dmp1 != NULL && - rsa->dmq1 != NULL && rsa->iqmp != NULL && + if (rsa->p != nullptr && rsa->q != nullptr && rsa->e != nullptr && + rsa->dmp1 != nullptr && rsa->dmq1 != nullptr && rsa->iqmp != nullptr && // Require that we can reduce |f| by |rsa->p| and |rsa->q| in constant // time, which requires primes be the same size, rounded to the Montgomery // coefficient. (See |mod_montgomery|.) This is not required by RFC 8017, // but it is true for keys generated by us and all common implementations. bn_less_than_montgomery_R(rsa->q, rsa->mont_p) && bn_less_than_montgomery_R(rsa->p, rsa->mont_q)) { - if (!rsa_mod_exp_crt(result, f, rsa, ctx)) { + if (!rsa_mod_exp_crt(result, f, rsa, ctx.get())) { goto err; } - } else if (!BN_mod_exp_mont_consttime(result, f, rsa->d_fixed, rsa->n, ctx, - rsa->mont_n)) { + } else if (!BN_mod_exp_mont_consttime(result, f, rsa->d_fixed, rsa->n, + ctx.get(), rsa->mont_n)) { goto err; } @@ -634,17 +626,19 @@ // // This check is cheap assuming |e| is small, which we require in // |rsa_check_public_key|. - if (rsa->e != NULL) { - BIGNUM *vrfy = BN_CTX_get(ctx); - if (vrfy == NULL || - !BN_mod_exp_mont(vrfy, result, rsa->e, rsa->n, ctx, rsa->mont_n) || + if (rsa->e != nullptr) { + BIGNUM *vrfy = BN_CTX_get(ctx.get()); + if (vrfy == nullptr || + !BN_mod_exp_mont(vrfy, result, rsa->e, rsa->n, ctx.get(), + rsa->mont_n) || !constant_time_declassify_int(BN_equal_consttime(vrfy, f))) { OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); goto err; } } - if (do_blinding && !BN_BLINDING_invert(result, blinding, rsa->mont_n, ctx)) { + if (do_blinding && + !BN_BLINDING_invert(result, blinding, rsa->mont_n, ctx.get())) { goto err; } @@ -663,11 +657,7 @@ ret = 1; err: - if (ctx != NULL) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - if (blinding != NULL) { + if (blinding != nullptr) { rsa_blinding_release(rsa, blinding, blinding_index); } @@ -717,23 +707,19 @@ assert(rsa->dmq1 != NULL); assert(rsa->iqmp != NULL); - BIGNUM *r1, *m1; - int ret = 0; - - BN_CTX_start(ctx); - r1 = BN_CTX_get(ctx); - m1 = BN_CTX_get(ctx); - BIGNUM *n, *p, *q; + bssl::BN_CTXScope scope(ctx); + BIGNUM *r1 = BN_CTX_get(ctx); + BIGNUM *m1 = BN_CTX_get(ctx); if (r1 == NULL || m1 == NULL) { - goto err; + return 0; } // Use the minimal-width versions of |n|, |p|, and |q|. Either works, but if // someone gives us non-minimal values, these will be slightly more efficient // on the non-Montgomery operations. - n = &rsa->mont_n->N; - p = &rsa->mont_p->N; - q = &rsa->mont_q->N; + BIGNUM *n = &rsa->mont_n->N; + BIGNUM *p = &rsa->mont_p->N; + BIGNUM *q = &rsa->mont_q->N; // This is a pre-condition for |mod_montgomery|. It was already checked by the // caller. @@ -766,7 +752,7 @@ // [0, n). !bn_mul_consttime(r0, r0, q, ctx) || // !bn_uadd_consttime(r0, r0, m1)) { - goto err; + return 0; } // The result should be bounded by |n|, but fixed-width operations may @@ -776,14 +762,10 @@ declassify_assert(BN_cmp(r0, n) < 0); bn_assert_fits_in_bytes(r0, BN_num_bytes(n)); if (!bn_resize_words(r0, n->width)) { - goto err; + return 0; } - ret = 1; - -err: - BN_CTX_end(ctx); - return ret; + return 1; } static int ensure_bignum(BIGNUM **out) { @@ -914,11 +896,11 @@ } int limit = BN_is_word(e, 3) ? bits * 8 : bits * 5; - int ret = 0, tries = 0, rand_tries = 0; - BN_CTX_start(ctx); + int tries = 0, rand_tries = 0; + bssl::BN_CTXScope scope(ctx); BIGNUM *tmp = BN_CTX_get(ctx); if (tmp == NULL) { - goto err; + return 0; } for (;;) { @@ -927,13 +909,13 @@ // bound checked below in steps 4.4 and 5.5). if (!BN_rand(out, bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD) || !BN_GENCB_call(cb, BN_GENCB_GENERATED, rand_tries++)) { - goto err; + return 0; } if (p != NULL) { // If |p| and |out| are too close, try again (step 5.4). if (!bn_abs_sub_consttime(tmp, out, p, ctx)) { - goto err; + return 0; } if (BN_cmp(tmp, pow2_bits_100) <= 0) { continue; @@ -963,18 +945,17 @@ int relatively_prime; if (!bn_usub_consttime(tmp, out, BN_value_one()) || !bn_is_relatively_prime(&relatively_prime, tmp, e, ctx)) { - goto err; + return 0; } if (constant_time_declassify_int(relatively_prime)) { // Test |out| for primality (steps 4.5.1 and 5.6.1). int is_probable_prime; if (!BN_primality_test(&is_probable_prime, out, BN_prime_checks_for_generation, ctx, 0, cb)) { - goto err; + return 0; } if (is_probable_prime) { - ret = 1; - goto err; + return 1; } } } @@ -984,16 +965,12 @@ tries++; if (tries >= limit) { OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_MANY_ITERATIONS); - goto err; + return 0; } if (!BN_GENCB_call(cb, 2, tries)) { - goto err; + return 0; } } - -err: - BN_CTX_end(ctx); - return ret; } // rsa_generate_key_impl generates an RSA key using a generalized version of @@ -1029,29 +1006,31 @@ return 0; } - int ret = 0; - int prime_bits = bits / 2; - BN_CTX *ctx = BN_CTX_new(); - BIGNUM *totient, *pm1, *qm1, *sqrt2, *pow2_prime_bits_100, *pow2_prime_bits; + bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new()); int sqrt2_bits; - if (ctx == NULL) { - goto bn_err; - } - BN_CTX_start(ctx); - totient = BN_CTX_get(ctx); - pm1 = BN_CTX_get(ctx); - qm1 = BN_CTX_get(ctx); - sqrt2 = BN_CTX_get(ctx); - pow2_prime_bits_100 = BN_CTX_get(ctx); - pow2_prime_bits = BN_CTX_get(ctx); - if (totient == NULL || pm1 == NULL || qm1 == NULL || sqrt2 == NULL || - pow2_prime_bits_100 == NULL || pow2_prime_bits == NULL || - !BN_set_bit(pow2_prime_bits_100, prime_bits - 100) || - !BN_set_bit(pow2_prime_bits, prime_bits)) { - goto bn_err; + if (ctx == nullptr) { + OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); + return 0; } - // We need the RSA components non-NULL. + int prime_bits = bits / 2; + bssl::BN_CTXScope scope(ctx.get()); + BIGNUM *totient = BN_CTX_get(ctx.get()); + BIGNUM *pm1 = BN_CTX_get(ctx.get()); + BIGNUM *qm1 = BN_CTX_get(ctx.get()); + BIGNUM *sqrt2 = BN_CTX_get(ctx.get()); + BIGNUM *pow2_prime_bits_100 = BN_CTX_get(ctx.get()); + BIGNUM *pow2_prime_bits = BN_CTX_get(ctx.get()); + if (totient == nullptr || pm1 == nullptr || qm1 == nullptr || + sqrt2 == nullptr || pow2_prime_bits_100 == nullptr || + pow2_prime_bits == nullptr || + !BN_set_bit(pow2_prime_bits_100, prime_bits - 100) || + !BN_set_bit(pow2_prime_bits, prime_bits)) { + OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); + return 0; + } + + // We need the RSA components non-null. if (!ensure_bignum(&rsa->n) || // !ensure_bignum(&rsa->d) || // !ensure_bignum(&rsa->e) || // @@ -1060,16 +1039,19 @@ !ensure_bignum(&rsa->dmp1) || // !ensure_bignum(&rsa->dmq1) || // !ensure_bignum(&rsa->iqmp)) { - goto bn_err; + OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); + return 0; } if (!BN_copy(rsa->e, e_value)) { - goto bn_err; + OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); + return 0; } // Compute sqrt2 >= ⌊2^(prime_bits-1)×√2⌋. if (!bn_set_words(sqrt2, kBoringSSLRSASqrtTwo, kBoringSSLRSASqrtTwoLen)) { - goto bn_err; + OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); + return 0; } sqrt2_bits = kBoringSSLRSASqrtTwoLen * BN_BITS2; assert(sqrt2_bits == (int)BN_num_bits(sqrt2)); @@ -1077,14 +1059,16 @@ // For key sizes up to 4096 (prime_bits = 2048), this is exactly // ⌊2^(prime_bits-1)×√2⌋. if (!BN_rshift(sqrt2, sqrt2, sqrt2_bits - prime_bits)) { - goto bn_err; + OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); + return 0; } } else if (prime_bits > sqrt2_bits) { // For key sizes beyond 4096, this is approximate. We err towards retrying // to ensure our key is the right size and round up. if (!BN_add_word(sqrt2, 1) || !BN_lshift(sqrt2, sqrt2, prime_bits - sqrt2_bits)) { - goto bn_err; + OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); + return 0; } } assert(prime_bits == (int)BN_num_bits(sqrt2)); @@ -1095,13 +1079,14 @@ // // Each call to |generate_prime| fails with probability p = 2^-21. The // probability that either call fails is 1 - (1-p)^2, which is around 2^-20. - if (!generate_prime(rsa->p, prime_bits, rsa->e, NULL, sqrt2, - pow2_prime_bits_100, ctx, cb) || + if (!generate_prime(rsa->p, prime_bits, rsa->e, nullptr, sqrt2, + pow2_prime_bits_100, ctx.get(), cb) || !BN_GENCB_call(cb, 3, 0) || !generate_prime(rsa->q, prime_bits, rsa->e, rsa->p, sqrt2, - pow2_prime_bits_100, ctx, cb) || + pow2_prime_bits_100, ctx.get(), cb) || !BN_GENCB_call(cb, 3, 1)) { - goto bn_err; + OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); + return 0; } if (BN_cmp(rsa->p, rsa->q) < 0) { @@ -1120,9 +1105,11 @@ int no_inverse; if (!bn_usub_consttime(pm1, rsa->p, BN_value_one()) || !bn_usub_consttime(qm1, rsa->q, BN_value_one()) || - !bn_lcm_consttime(totient, pm1, qm1, ctx) || - !bn_mod_inverse_consttime(rsa->d, &no_inverse, rsa->e, totient, ctx)) { - goto bn_err; + !bn_lcm_consttime(totient, pm1, qm1, ctx.get()) || + !bn_mod_inverse_consttime(rsa->d, &no_inverse, rsa->e, totient, + ctx.get())) { + OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); + return 0; } // Retry if |rsa->d| <= 2^|prime_bits|. See appendix B.3.1's guidance on @@ -1133,12 +1120,15 @@ assert(BN_num_bits(pm1) == (unsigned)prime_bits); assert(BN_num_bits(qm1) == (unsigned)prime_bits); if ( // Calculate n. - !bn_mul_consttime(rsa->n, rsa->p, rsa->q, ctx) || + !bn_mul_consttime(rsa->n, rsa->p, rsa->q, ctx.get()) || // Calculate d mod (p-1). - !bn_div_consttime(NULL, rsa->dmp1, rsa->d, pm1, prime_bits, ctx) || + !bn_div_consttime(nullptr, rsa->dmp1, rsa->d, pm1, prime_bits, + ctx.get()) || // Calculate d mod (q-1) - !bn_div_consttime(NULL, rsa->dmq1, rsa->d, qm1, prime_bits, ctx)) { - goto bn_err; + !bn_div_consttime(nullptr, rsa->dmq1, rsa->d, qm1, prime_bits, + ctx.get())) { + OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); + return 0; } bn_set_minimal_width(rsa->n); @@ -1146,41 +1136,30 @@ bn_declassify(rsa->n); // Calculate q^-1 mod p. - rsa->mont_p = BN_MONT_CTX_new_consttime(rsa->p, ctx); - if (rsa->mont_p == NULL || // - !bn_mod_inverse_secret_prime(rsa->iqmp, rsa->q, rsa->p, ctx, + rsa->mont_p = BN_MONT_CTX_new_consttime(rsa->p, ctx.get()); + if (rsa->mont_p == nullptr || // + !bn_mod_inverse_secret_prime(rsa->iqmp, rsa->q, rsa->p, ctx.get(), rsa->mont_p)) { - goto bn_err; + OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); + return 0; } // Sanity-check that |rsa->n| has the specified size. This is implied by // |generate_prime|'s bounds. if (BN_num_bits(rsa->n) != (unsigned)bits) { OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); - goto err; + return 0; } // The key generation process is complex and thus error-prone. It could be // disastrous to generate and then use a bad key so double-check that the key // makes sense. Also, while |rsa| is mutable, fill in the cached components. - if (!RSA_check_key(rsa) || - !freeze_private_key(rsa, ctx)) { + if (!RSA_check_key(rsa) || !freeze_private_key(rsa, ctx.get())) { OPENSSL_PUT_ERROR(RSA, RSA_R_INTERNAL_ERROR); - goto err; + return 0; } - ret = 1; - -bn_err: - if (!ret) { - OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); - } -err: - if (ctx != NULL) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - return ret; + return 1; } static void replace_bignum(BIGNUM **out, BIGNUM **in) {
diff --git a/crypto/rsa/rsa_crypt.cc b/crypto/rsa/rsa_crypt.cc index acf207e..ce4ae7d 100644 --- a/crypto/rsa/rsa_crypt.cc +++ b/crypto/rsa/rsa_crypt.cc
@@ -349,25 +349,21 @@ } const unsigned rsa_size = RSA_size(rsa); - BIGNUM *f, *result; - uint8_t *buf = NULL; - BN_CTX *ctx = NULL; - int i, ret = 0; - if (max_out < rsa_size) { OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL); return 0; } - ctx = BN_CTX_new(); - if (ctx == NULL) { - goto err; + bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new()); + if (ctx == nullptr) { + return 0; } - BN_CTX_start(ctx); - f = BN_CTX_get(ctx); - result = BN_CTX_get(ctx); - buf = reinterpret_cast<uint8_t *>(OPENSSL_malloc(rsa_size)); + bssl::BN_CTXScope scope(ctx.get()); + BIGNUM *f = BN_CTX_get(ctx.get()); + BIGNUM *result = BN_CTX_get(ctx.get()); + uint8_t *buf = reinterpret_cast<uint8_t *>(OPENSSL_malloc(rsa_size)); + int i, ret = 0; if (!f || !result || !buf) { goto err; } @@ -378,8 +374,8 @@ break; case RSA_PKCS1_OAEP_PADDING: // Use the default parameters: SHA-1 for both hashes and no label. - i = RSA_padding_add_PKCS1_OAEP_mgf1(buf, rsa_size, in, in_len, NULL, 0, - NULL, NULL); + i = RSA_padding_add_PKCS1_OAEP_mgf1(buf, rsa_size, in, in_len, nullptr, 0, + nullptr, nullptr); break; case RSA_NO_PADDING: i = RSA_padding_add_none(buf, rsa_size, in, in_len); @@ -393,7 +389,7 @@ goto err; } - if (BN_bin2bn(buf, rsa_size, f) == NULL) { + if (BN_bin2bn(buf, rsa_size, f) == nullptr) { goto err; } @@ -403,8 +399,9 @@ goto err; } - if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) || - !BN_mod_exp_mont(result, f, rsa->e, &rsa->mont_n->N, ctx, rsa->mont_n)) { + if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx.get()) || + !BN_mod_exp_mont(result, f, rsa->e, &rsa->mont_n->N, ctx.get(), + rsa->mont_n)) { goto err; } @@ -419,12 +416,7 @@ ret = 1; err: - if (ctx != NULL) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } OPENSSL_free(buf); - return ret; }
diff --git a/gen/sources.bzl b/gen/sources.bzl index 03ce8b8..758f8e7 100644 --- a/gen/sources.bzl +++ b/gen/sources.bzl
@@ -303,7 +303,9 @@ "crypto/blake2/blake2.cc", "crypto/bn/bn_asn1.cc", "crypto/bn/convert.cc", + "crypto/bn/div.cc", "crypto/bn/exponentiation.cc", + "crypto/bn/sqrt.cc", "crypto/buf/buf.cc", "crypto/bytestring/asn1_compat.cc", "crypto/bytestring/ber.cc", @@ -1122,6 +1124,15 @@ "fuzz/verify_name_match_verifynameinsubtree_fuzzer.cc", ] +modulewrapper_sources = [ + "util/fipstools/acvp/modulewrapper/main.cc", + "util/fipstools/acvp/modulewrapper/modulewrapper.cc", +] + +modulewrapper_internal_headers = [ + "util/fipstools/acvp/modulewrapper/modulewrapper.h", +] + pki_sources = [ "pki/cert_error_id.cc", "pki/cert_error_params.cc",
diff --git a/gen/sources.cmake b/gen/sources.cmake index 5ae6e0f..32aaf2b 100644 --- a/gen/sources.cmake +++ b/gen/sources.cmake
@@ -317,7 +317,9 @@ crypto/blake2/blake2.cc crypto/bn/bn_asn1.cc crypto/bn/convert.cc + crypto/bn/div.cc crypto/bn/exponentiation.cc + crypto/bn/sqrt.cc crypto/buf/buf.cc crypto/bytestring/asn1_compat.cc crypto/bytestring/ber.cc @@ -1157,6 +1159,19 @@ ) set( + MODULEWRAPPER_SOURCES + + util/fipstools/acvp/modulewrapper/main.cc + util/fipstools/acvp/modulewrapper/modulewrapper.cc +) + +set( + MODULEWRAPPER_INTERNAL_HEADERS + + util/fipstools/acvp/modulewrapper/modulewrapper.h +) + +set( PKI_SOURCES pki/cert_error_id.cc
diff --git a/gen/sources.gni b/gen/sources.gni index e4079f1..cd760e2 100644 --- a/gen/sources.gni +++ b/gen/sources.gni
@@ -303,7 +303,9 @@ "crypto/blake2/blake2.cc", "crypto/bn/bn_asn1.cc", "crypto/bn/convert.cc", + "crypto/bn/div.cc", "crypto/bn/exponentiation.cc", + "crypto/bn/sqrt.cc", "crypto/buf/buf.cc", "crypto/bytestring/asn1_compat.cc", "crypto/bytestring/ber.cc", @@ -1122,6 +1124,15 @@ "fuzz/verify_name_match_verifynameinsubtree_fuzzer.cc", ] +modulewrapper_sources = [ + "util/fipstools/acvp/modulewrapper/main.cc", + "util/fipstools/acvp/modulewrapper/modulewrapper.cc", +] + +modulewrapper_internal_headers = [ + "util/fipstools/acvp/modulewrapper/modulewrapper.h", +] + pki_sources = [ "pki/cert_error_id.cc", "pki/cert_error_params.cc",
diff --git a/gen/sources.json b/gen/sources.json index 8f4e1a4..fb27719 100644 --- a/gen/sources.json +++ b/gen/sources.json
@@ -287,7 +287,9 @@ "crypto/blake2/blake2.cc", "crypto/bn/bn_asn1.cc", "crypto/bn/convert.cc", + "crypto/bn/div.cc", "crypto/bn/exponentiation.cc", + "crypto/bn/sqrt.cc", "crypto/buf/buf.cc", "crypto/bytestring/asn1_compat.cc", "crypto/bytestring/ber.cc", @@ -1104,6 +1106,15 @@ "fuzz/verify_name_match_verifynameinsubtree_fuzzer.cc" ] }, + "modulewrapper": { + "srcs": [ + "util/fipstools/acvp/modulewrapper/main.cc", + "util/fipstools/acvp/modulewrapper/modulewrapper.cc" + ], + "internal_hdrs": [ + "util/fipstools/acvp/modulewrapper/modulewrapper.h" + ] + }, "pki": { "srcs": [ "pki/cert_error_id.cc",
diff --git a/gen/sources.mk b/gen/sources.mk index 02effd9..b6888fa 100644 --- a/gen/sources.mk +++ b/gen/sources.mk
@@ -297,7 +297,9 @@ crypto/blake2/blake2.cc \ crypto/bn/bn_asn1.cc \ crypto/bn/convert.cc \ + crypto/bn/div.cc \ crypto/bn/exponentiation.cc \ + crypto/bn/sqrt.cc \ crypto/buf/buf.cc \ crypto/bytestring/asn1_compat.cc \ crypto/bytestring/ber.cc \ @@ -1105,6 +1107,13 @@ fuzz/verify_name_match_normalizename_fuzzer.cc \ fuzz/verify_name_match_verifynameinsubtree_fuzzer.cc +boringssl_modulewrapper_sources := \ + util/fipstools/acvp/modulewrapper/main.cc \ + util/fipstools/acvp/modulewrapper/modulewrapper.cc + +boringssl_modulewrapper_internal_headers := \ + util/fipstools/acvp/modulewrapper/modulewrapper.h + boringssl_pki_sources := \ pki/cert_error_id.cc \ pki/cert_error_params.cc \
diff --git a/util/fipstools/CMakeLists.txt b/util/fipstools/CMakeLists.txt deleted file mode 100644 index ff33b4f..0000000 --- a/util/fipstools/CMakeLists.txt +++ /dev/null
@@ -1,6 +0,0 @@ -add_executable( - test_fips - - test_fips.cc -) -target_link_libraries(test_fips crypto)
diff --git a/util/fipstools/acvp/acvptool/acvp.go b/util/fipstools/acvp/acvptool/acvp.go index dcaf542..7a5c43c 100644 --- a/util/fipstools/acvp/acvptool/acvp.go +++ b/util/fipstools/acvp/acvptool/acvp.go
@@ -51,7 +51,7 @@ runFlag = flag.String("run", "", "Name of primitive to run tests for") fetchFlag = flag.String("fetch", "", "Name of primitive to fetch vectors for") expectedOutFlag = flag.String("expected-out", "", "Name of a file to write the expected results to") - wrapperPath = flag.String("wrapper", "../../../../build/util/fipstools/acvp/modulewrapper/modulewrapper", "Path to the wrapper binary") + wrapperPath = flag.String("wrapper", "../../../../build/modulewrapper", "Path to the wrapper binary") ) type Config struct {
diff --git a/util/fipstools/acvp/acvptool/subprocess/subprocess.go b/util/fipstools/acvp/acvptool/subprocess/subprocess.go index f550cf0..78e69ce 100644 --- a/util/fipstools/acvp/acvptool/subprocess/subprocess.go +++ b/util/fipstools/acvp/acvptool/subprocess/subprocess.go
@@ -371,8 +371,6 @@ m.supportsFlush = true } } - } else if _, ok := m.primitives[algo.Algorithm]; !ok { - return nil, fmt.Errorf("wrapper config advertises support for unknown algorithm %q", algo.Algorithm) } }
diff --git a/util/fipstools/acvp/acvptool/test/expected/CMAC-AES.bz2 b/util/fipstools/acvp/acvptool/test/expected/CMAC-AES.bz2 index f80e502..5c71478 100644 --- a/util/fipstools/acvp/acvptool/test/expected/CMAC-AES.bz2 +++ b/util/fipstools/acvp/acvptool/test/expected/CMAC-AES.bz2 Binary files differ
diff --git a/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA-1.bz2 b/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA-1.bz2 index a95786d..de6c60f 100644 --- a/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA-1.bz2 +++ b/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA-1.bz2 Binary files differ
diff --git a/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-224.bz2 b/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-224.bz2 index c8ab1f9..8a14531 100644 --- a/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-224.bz2 +++ b/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-224.bz2 Binary files differ
diff --git a/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-256.bz2 b/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-256.bz2 index 1090835..6639cf0 100644 --- a/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-256.bz2 +++ b/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-256.bz2 Binary files differ
diff --git a/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-384.bz2 b/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-384.bz2 index 5b445a5..8d799b7 100644 --- a/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-384.bz2 +++ b/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-384.bz2 Binary files differ
diff --git a/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-512-256.bz2 b/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-512-256.bz2 index 1fdfa42..5f869cd 100644 --- a/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-512-256.bz2 +++ b/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-512-256.bz2 Binary files differ
diff --git a/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-512.bz2 b/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-512.bz2 index 3e46724..a1b2fd4 100644 --- a/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-512.bz2 +++ b/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-512.bz2 Binary files differ
diff --git a/util/fipstools/acvp/acvptool/test/trim_vectors.go b/util/fipstools/acvp/acvptool/test/trim_vectors.go index 33dc947..59e5791 100644 --- a/util/fipstools/acvp/acvptool/test/trim_vectors.go +++ b/util/fipstools/acvp/acvptool/test/trim_vectors.go
@@ -15,11 +15,13 @@ //go:build ignore // trimvectors takes an ACVP vector set file and discards all but a single test -// from each test group. This hope is that this achieves good coverage without -// having to check in megabytes worth of JSON files. +// from each test group, and also discards any test that serializes to more than +// 4096 bytes. This hope is that this achieves good coverage without having to +// check in megabytes worth of JSON files. package main import ( + "bytes" "encoding/json" "os" ) @@ -39,12 +41,22 @@ testGroup := testGroupInterface.(map[string]any) tests := testGroup["tests"].([]any) - keepIndex := 10 - if keepIndex >= len(tests) { - keepIndex = len(tests) - 1 + var keptTests []any + for _, test := range tests { + var b bytes.Buffer + encoder := json.NewEncoder(&b) + if err := encoder.Encode(test); err != nil { + panic(err) + } + if b.Len() <= 4096 { + keptTests = append(keptTests, test) + } + // We only keep the first test that meets the size criteria. + if len(keptTests) >= 1 { + break + } } - - testGroup["tests"] = []any{tests[keepIndex]} + testGroup["tests"] = keptTests } }
diff --git a/util/fipstools/acvp/acvptool/test/vectors/CMAC-AES.bz2 b/util/fipstools/acvp/acvptool/test/vectors/CMAC-AES.bz2 index ff34573..f38d822 100644 --- a/util/fipstools/acvp/acvptool/test/vectors/CMAC-AES.bz2 +++ b/util/fipstools/acvp/acvptool/test/vectors/CMAC-AES.bz2 Binary files differ
diff --git a/util/fipstools/acvp/acvptool/test/vectors/HMAC-SHA-1.bz2 b/util/fipstools/acvp/acvptool/test/vectors/HMAC-SHA-1.bz2 index d427f2e..b379dee 100644 --- a/util/fipstools/acvp/acvptool/test/vectors/HMAC-SHA-1.bz2 +++ b/util/fipstools/acvp/acvptool/test/vectors/HMAC-SHA-1.bz2 Binary files differ
diff --git a/util/fipstools/acvp/acvptool/test/vectors/HMAC-SHA2-224.bz2 b/util/fipstools/acvp/acvptool/test/vectors/HMAC-SHA2-224.bz2 index dd67b61..62b52d4 100644 --- a/util/fipstools/acvp/acvptool/test/vectors/HMAC-SHA2-224.bz2 +++ b/util/fipstools/acvp/acvptool/test/vectors/HMAC-SHA2-224.bz2 Binary files differ
diff --git a/util/fipstools/acvp/acvptool/test/vectors/HMAC-SHA2-256.bz2 b/util/fipstools/acvp/acvptool/test/vectors/HMAC-SHA2-256.bz2 index b137466..5cb072a 100644 --- a/util/fipstools/acvp/acvptool/test/vectors/HMAC-SHA2-256.bz2 +++ b/util/fipstools/acvp/acvptool/test/vectors/HMAC-SHA2-256.bz2 Binary files differ
diff --git a/util/fipstools/acvp/acvptool/test/vectors/HMAC-SHA2-384.bz2 b/util/fipstools/acvp/acvptool/test/vectors/HMAC-SHA2-384.bz2 index 2c1b317..6d1eb6d 100644 --- a/util/fipstools/acvp/acvptool/test/vectors/HMAC-SHA2-384.bz2 +++ b/util/fipstools/acvp/acvptool/test/vectors/HMAC-SHA2-384.bz2 Binary files differ
diff --git a/util/fipstools/acvp/acvptool/test/vectors/HMAC-SHA2-512-256.bz2 b/util/fipstools/acvp/acvptool/test/vectors/HMAC-SHA2-512-256.bz2 index d981300..68b34e0 100644 --- a/util/fipstools/acvp/acvptool/test/vectors/HMAC-SHA2-512-256.bz2 +++ b/util/fipstools/acvp/acvptool/test/vectors/HMAC-SHA2-512-256.bz2 Binary files differ
diff --git a/util/fipstools/acvp/acvptool/test/vectors/HMAC-SHA2-512.bz2 b/util/fipstools/acvp/acvptool/test/vectors/HMAC-SHA2-512.bz2 index a3ffe61..5ce2742 100644 --- a/util/fipstools/acvp/acvptool/test/vectors/HMAC-SHA2-512.bz2 +++ b/util/fipstools/acvp/acvptool/test/vectors/HMAC-SHA2-512.bz2 Binary files differ
diff --git a/util/fipstools/acvp/modulewrapper/CMakeLists.txt b/util/fipstools/acvp/modulewrapper/CMakeLists.txt deleted file mode 100644 index 7938d39..0000000 --- a/util/fipstools/acvp/modulewrapper/CMakeLists.txt +++ /dev/null
@@ -1,9 +0,0 @@ -if(FIPS) - add_executable( - modulewrapper - - main.cc - modulewrapper.cc - ) - target_link_libraries(modulewrapper crypto) -endif()
diff --git a/util/fipstools/break-tests.sh b/util/fipstools/break-tests.sh index e056e8f..111f120 100644 --- a/util/fipstools/break-tests.sh +++ b/util/fipstools/break-tests.sh
@@ -128,7 +128,7 @@ } if [ "$MODE" = "local" ]; then - TEST_FIPS_BIN=${TEST_FIPS_BIN:-build/util/fipstools/test_fips} + TEST_FIPS_BIN=${TEST_FIPS_BIN:-build/test_fips} TEST_FIPS_BREAK_BIN=${TEST_FIPS_BREAK_BIN:-./test_fips_break} check_file "$TEST_FIPS_BIN" check_file "$TEST_FIPS_BREAK_BIN"
diff --git a/util/fipstools/test-break-kat.sh b/util/fipstools/test-break-kat.sh index b3b6283..01c13c3 100644 --- a/util/fipstools/test-break-kat.sh +++ b/util/fipstools/test-break-kat.sh
@@ -18,7 +18,7 @@ set -x set -e -TEST_FIPS_BIN="build/util/fipstools/test_fips" +TEST_FIPS_BIN="build/test_fips" if [ ! -f $TEST_FIPS_BIN ]; then echo "$TEST_FIPS_BIN is missing. Run this script from the top level of a"