From 5826a075e6186ff85c4383b8f0e051d50783cc2c Mon Sep 17 00:00:00 2001 From: Sean McGrail <549813+skmcgrail@users.noreply.github.com> Date: Thu, 6 Mar 2025 18:39:08 +0000 Subject: [PATCH 1/9] Make BIO_get_mem_data a function again (#2246) ### Description of changes: Can't track it down the historical reason why, but we have `BIO_get_mem_data` defined as a preprocessor macro, but BoringSSL does not. This creates an annoying compatibility issue for rust-openssl, and has forced us to implement the function properly in our aws-lc-sys crates in Rust. This redefines the function to have a concrete definition. As a side-note, the macro was technically wrong as it was casting contents to a `char *` when it was actually `char **`, but this wasn't problematic per-se since it was being passed into a `void *` argument. If you look at the ctrl function definition you can see that it is indeed treated as a `char **` pointer. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license. --- crypto/bio/bio_mem.c | 4 ++++ include/openssl/bio.h | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/crypto/bio/bio_mem.c b/crypto/bio/bio_mem.c index 54243f9df4..7b7965094b 100644 --- a/crypto/bio/bio_mem.c +++ b/crypto/bio/bio_mem.c @@ -296,6 +296,10 @@ int BIO_mem_contents(const BIO *bio, const uint8_t **out_contents, return 1; } +long BIO_get_mem_data(BIO *bio, char **contents) { + return BIO_ctrl(bio, BIO_CTRL_INFO, 0, contents); +} + int BIO_get_mem_ptr(BIO *bio, BUF_MEM **out) { return (int)BIO_ctrl(bio, BIO_C_GET_BUF_MEM_PTR, 0, out); } diff --git a/include/openssl/bio.h b/include/openssl/bio.h index ddc1a265cb..c5f44bad5c 100644 --- a/include/openssl/bio.h +++ b/include/openssl/bio.h @@ -454,8 +454,8 @@ OPENSSL_EXPORT int BIO_mem_contents(const BIO *bio, // WARNING: don't use this, use |BIO_mem_contents|. A negative return value // or zero from this function can mean either that it failed or that the // memory buffer is empty. -#define BIO_get_mem_data(bio, contents) BIO_ctrl(bio, BIO_CTRL_INFO, 0, \ - (char *)(contents)) +OPENSSL_EXPORT long BIO_get_mem_data(BIO *bio, char **contents); + // BIO_get_mem_ptr sets |*out| to a BUF_MEM containing the current contents of // |bio|. It returns one on success or zero on error. OPENSSL_EXPORT int BIO_get_mem_ptr(BIO *bio, BUF_MEM **out); From d0356099f6b668697cdb381dfb09f9a694a6c9c2 Mon Sep 17 00:00:00 2001 From: Sean McGrail <549813+skmcgrail@users.noreply.github.com> Date: Thu, 6 Mar 2025 20:20:11 +0000 Subject: [PATCH 2/9] Prepare v1.48.1 (#2252) ## What's Changed * Move OCSP ASN1 type functions to public header by @skmcgrail in https://github.com/aws/aws-lc/pull/2239 * Make BIO_get_mem_data a function again by @skmcgrail in https://github.com/aws/aws-lc/pull/2246 By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license. --- crypto/fipsmodule/service_indicator/service_indicator_test.cc | 4 ++-- include/openssl/base.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crypto/fipsmodule/service_indicator/service_indicator_test.cc b/crypto/fipsmodule/service_indicator/service_indicator_test.cc index 8ae8f7e7ae..f73434303b 100644 --- a/crypto/fipsmodule/service_indicator/service_indicator_test.cc +++ b/crypto/fipsmodule/service_indicator/service_indicator_test.cc @@ -5296,7 +5296,7 @@ TEST(ServiceIndicatorTest, ED25519SigGenVerify) { // Since this is running in FIPS mode it should end in FIPS // Update this when the AWS-LC version number is modified TEST(ServiceIndicatorTest, AWSLCVersionString) { - ASSERT_STREQ(awslc_version_string(), "AWS-LC FIPS 1.48.0"); + ASSERT_STREQ(awslc_version_string(), "AWS-LC FIPS 1.48.1"); } #else @@ -5339,6 +5339,6 @@ TEST(ServiceIndicatorTest, BasicTest) { // Since this is not running in FIPS mode it shouldn't end in FIPS // Update this when the AWS-LC version number is modified TEST(ServiceIndicatorTest, AWSLCVersionString) { - ASSERT_STREQ(awslc_version_string(), "AWS-LC 1.48.0"); + ASSERT_STREQ(awslc_version_string(), "AWS-LC 1.48.1"); } #endif // AWSLC_FIPS diff --git a/include/openssl/base.h b/include/openssl/base.h index 7c5dba27af..af5e008b94 100644 --- a/include/openssl/base.h +++ b/include/openssl/base.h @@ -122,7 +122,7 @@ extern "C" { // ServiceIndicatorTest.AWSLCVersionString // Note: there are two versions of this test. Only one test is compiled // depending on FIPS mode. -#define AWSLC_VERSION_NUMBER_STRING "1.48.0" +#define AWSLC_VERSION_NUMBER_STRING "1.48.1" #if defined(BORINGSSL_SHARED_LIBRARY) From 4fb8ec366e35007b2c01226a6407bb4e67ef61a8 Mon Sep 17 00:00:00 2001 From: Shubham Mittal <107728331+smittals2@users.noreply.github.com> Date: Thu, 6 Mar 2025 15:44:51 -0800 Subject: [PATCH 3/9] Add public wrapper to internal bn_minimal_width function (#2245) ### Description of changes: This PR adds a public wrapper for an existing internal function bn_minimal_width. OpenSSL stores the minimal number of words needed in a field called top within the bignum struct. AWS-LC does not do this, instead we have a field called width which is a loose upper bound on this value. The new function, BN_get_minimal_width will provide us with the value of "top" for a given Bignum. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license. --- crypto/fipsmodule/bn/bn.c | 4 ++++ include/openssl/bn.h | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/crypto/fipsmodule/bn/bn.c b/crypto/fipsmodule/bn/bn.c index ff78bbcdef..ea2b6a91f5 100644 --- a/crypto/fipsmodule/bn/bn.c +++ b/crypto/fipsmodule/bn/bn.c @@ -231,6 +231,10 @@ unsigned BN_num_bytes(const BIGNUM *bn) { return (BN_num_bits(bn) + 7) / 8; } +int BN_get_minimal_width(const BIGNUM *bn) { + return bn_minimal_width(bn); +} + void BN_zero(BIGNUM *bn) { bn->width = bn->neg = 0; } diff --git a/include/openssl/bn.h b/include/openssl/bn.h index f96eae79bb..4740c7837a 100644 --- a/include/openssl/bn.h +++ b/include/openssl/bn.h @@ -222,6 +222,10 @@ OPENSSL_EXPORT unsigned BN_num_bits(const BIGNUM *bn); // will always fit in |int|. OPENSSL_EXPORT unsigned BN_num_bytes(const BIGNUM *bn); +// BN_get_minimal_width returns the minimal number of words needed to represent +// |bn|. +OPENSSL_EXPORT int BN_get_minimal_width(const BIGNUM *bn); + // BN_zero sets |bn| to zero. OPENSSL_EXPORT void BN_zero(BIGNUM *bn); From 5054cf00b351beb31bd9f669322f7e893d1dbe56 Mon Sep 17 00:00:00 2001 From: Shubham Mittal <107728331+smittals2@users.noreply.github.com> Date: Fri, 7 Mar 2025 10:14:57 -0800 Subject: [PATCH 4/9] Add LibRdKafka to our CI (#2225) ### Issues: `CryptoAlg-2863` ### Description of changes: Add librdkafka upstream to our CI. This was added as a Github action to allow running the librdkafka tests. These tests require spinning up a kafka cluster which was running into issues in docker/codebuild. The patchfile in this PR is only to allow running a specific testing target in librdkafka. We do not need this patchfile for compatibility. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license. --- .github/workflows/integrations.yml | 16 +++- .../librdkafka_patch/librdkafka-testing.patch | 13 ++++ .../integration/run_librdkafka_integration.sh | 77 +++++++++++++++++++ 3 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 tests/ci/integration/librdkafka_patch/librdkafka-testing.patch create mode 100755 tests/ci/integration/run_librdkafka_integration.sh diff --git a/.github/workflows/integrations.yml b/.github/workflows/integrations.yml index 8e45b0a77e..82325b8119 100644 --- a/.github/workflows/integrations.yml +++ b/.github/workflows/integrations.yml @@ -34,4 +34,18 @@ jobs: - uses: actions/checkout@v4 - name: Run libevent build run: | - ./tests/ci/integration/run_libevent_integration.sh \ No newline at end of file + ./tests/ci/integration/run_libevent_integration.sh + librdkafka: + if: github.repository_owner == 'aws' + runs-on: ubuntu-latest + steps: + - name: Install OS Dependencies + run: | + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none + sudo apt-get -y --no-install-recommends install \ + cmake gcc ninja-build golang + - uses: actions/checkout@v4 + - name: Run librdkafka build + run: | + ./tests/ci/integration/run_librdkafka_integration.sh + \ No newline at end of file diff --git a/tests/ci/integration/librdkafka_patch/librdkafka-testing.patch b/tests/ci/integration/librdkafka_patch/librdkafka-testing.patch new file mode 100644 index 0000000000..e8683bc822 --- /dev/null +++ b/tests/ci/integration/librdkafka_patch/librdkafka-testing.patch @@ -0,0 +1,13 @@ +diff --git a/tests/Makefile b/tests/Makefile +index 543639e4..41791162 100644 +--- a/tests/Makefile ++++ b/tests/Makefile +@@ -51,7 +51,7 @@ full: broker broker_idempotent sasl + # + # The following targets require an existing cluster running (test.conf) + # +-quick: ++quick: $(BIN) + @echo "Running quick(er) test suite (without sockem)" + ./run-test.sh -Q -E + diff --git a/tests/ci/integration/run_librdkafka_integration.sh b/tests/ci/integration/run_librdkafka_integration.sh new file mode 100755 index 0000000000..acd6695b75 --- /dev/null +++ b/tests/ci/integration/run_librdkafka_integration.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 OR ISC + +set -ex + +source tests/ci/common_posix_setup.sh + +# Set up environment. + +# SYS_ROOT +# - SRC_ROOT(aws-lc) +# - SCRATCH_FOLDER +# - KAFKA_SRC_FOLDER +# - AWS_LC_BUILD_FOLDER +# - AWS_LC_INSTALL_FOLDER + +# Assumes script is executed from the root of aws-lc directory +SCRATCH_FOLDER="${SRC_ROOT}/KAFKA_BUILD_ROOT" +KAFKA_SRC_FOLDER="${SCRATCH_FOLDER}/librdkafka" +KAFKA_BUILD_PREFIX="${KAFKA_SRC_FOLDER}/build/install" +KAFKA_TEST_PATCH_FOLDER="${SRC_ROOT}/tests/ci/integration/librdkafka_patch" +AWS_LC_BUILD_FOLDER="${SCRATCH_FOLDER}/aws-lc-build" +AWS_LC_INSTALL_FOLDER="${SCRATCH_FOLDER}/aws-lc-install" + +mkdir -p ${SCRATCH_FOLDER} +rm -rf "${SCRATCH_FOLDER:?}"/* +cd ${SCRATCH_FOLDER} + +function kafka_build() { + export CFLAGS="-I${AWS_LC_INSTALL_FOLDER}/include ${CFLAGS}" + export CXXFLAGS="-I${AWS_LC_INSTALL_FOLDER}/include ${CXXFLAGS}" + export LDFLAGS="-L${AWS_LC_INSTALL_FOLDER}/lib ${LDFLAGS}" + export LD_LIBRARY_PATH="${AWS_LC_INSTALL_FOLDER}/lib" + + ./configure --prefix="$KAFKA_BUILD_PREFIX" + make -j install + make check + + local kafka_executable="${KAFKA_BUILD_PREFIX}/lib/librdkafka.so" + ldd ${kafka_executable} \ + | grep "${AWS_LC_INSTALL_FOLDER}/lib/libcrypto.so" || exit 1 +} + +function kafka_run_tests() { + export LD_LIBRARY_PATH="${AWS_LC_INSTALL_FOLDER}/lib" + python3 -m venv venv + source venv/bin/activate + + pushd ${KAFKA_SRC_FOLDER}/tests + python3 -m pip install -U -r requirements.txt + python3 -m trivup.clusters.KafkaCluster --version 2.8.0 << EOF + TESTS_SKIP=0092,0113 make -j quick + exit +EOF +} + +# This patch is only needed to execute the tests. A run_test executable is not +# available with the make quick target, this patch allows us to build that executable first. +function kafka_patch_test() { + patchfile="${KAFKA_TEST_PATCH_FOLDER}/librdkafka-testing.patch" + echo "Apply patch $patchfile..." + patch -p1 --quiet -i "$patchfile" +} + +git clone https://github.com/confluentinc/librdkafka.git ${KAFKA_SRC_FOLDER} +mkdir -p ${AWS_LC_BUILD_FOLDER} ${AWS_LC_INSTALL_FOLDER} +ls + +aws_lc_build "$SRC_ROOT" "$AWS_LC_BUILD_FOLDER" "$AWS_LC_INSTALL_FOLDER" -DCMAKE_INSTALL_LIBDIR=lib -DBUILD_TESTING=OFF -DBUILD_TOOL=OFF -DCMAKE_BUILD_TYPE=Debug -DBUILD_SHARED_LIBS=1 + +# Build openvpn from source. +pushd ${KAFKA_SRC_FOLDER} +kafka_patch_test +kafka_build +kafka_run_tests +popd From cd3b9cd6a73f578e1bb202f2275ab303e7c95cb4 Mon Sep 17 00:00:00 2001 From: Jonathon K <159580656+kingstjo@users.noreply.github.com> Date: Fri, 7 Mar 2025 14:37:57 -0800 Subject: [PATCH 5/9] Adding no-op X509_TRUST_cleanup for select application compatibility (#2257) ### Description of changes: - Re-implements X509_TRUST_cleanup() as a No-Op function after previous removal - Function was removed in commit #74c1f2a but is needed for select consuming applications - Added documentation explaining AWS-LC's different approach to trust settings ### Testing: - No regression testing needed (No-Op implementation) By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license. --- crypto/x509/x509_trs.c | 10 ++++++++++ include/openssl/x509.h | 5 +++++ 2 files changed, 15 insertions(+) diff --git a/crypto/x509/x509_trs.c b/crypto/x509/x509_trs.c index 530daf2145..856fd4f985 100644 --- a/crypto/x509/x509_trs.c +++ b/crypto/x509/x509_trs.c @@ -139,6 +139,16 @@ char *X509_TRUST_get0_name(const X509_TRUST *xp) { return xp->name; } int X509_TRUST_get_trust(const X509_TRUST *xp) { return xp->trust; } +void X509_TRUST_cleanup(void) { + // This is an intentional No-Op (no operation) function. + // + // Historical Context: + // - This function existed in OpenSSL versions prior to 1.1.0 + // - AWS-LC does not support static trust settings storage + // + // - Kept for API compatibility with older versions +} + static int trust_1oidany(const X509_TRUST *trust, X509 *x) { if (x->aux && (x->aux->trust || x->aux->reject)) { return obj_trust(trust->arg1, x); diff --git a/include/openssl/x509.h b/include/openssl/x509.h index 185d29b9d8..b07f84a00a 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h @@ -5090,6 +5090,11 @@ OPENSSL_EXPORT int X509_TRUST_get_by_id(int id); OPENSSL_EXPORT int X509_TRUST_get_flags(const X509_TRUST *xp); OPENSSL_EXPORT char *X509_TRUST_get0_name(const X509_TRUST *xp); OPENSSL_EXPORT int X509_TRUST_get_trust(const X509_TRUST *xp); +// X509_TRUST_cleanup intentionally does nothing. +// This function is maintained only for compatibility with applications +// that consume OpenSSL APIs. AWS-LC does not support the related +// static trust settings functions which were also deprecated in OpenSSL 1.1.0. +OPENSSL_EXPORT OPENSSL_DEPRECATED void X509_TRUST_cleanup(void); #define X509_LU_NONE 0 #define X509_LU_X509 1 From b4d7108a6d36ae079a9d8308248bbffc26369813 Mon Sep 17 00:00:00 2001 From: Andrew Hopkins Date: Fri, 7 Mar 2025 15:00:11 -0800 Subject: [PATCH 6/9] Remove unused CMake options for break tests (#2249) ### Description of changes: Setting the CMake option FIPS_BREAK_TEST to something like FFC_DH would result in defining `BORINGSSL_FIPS_BREAK_FFC_DH=1` which used to be how the break tests were broken. break-kat.go replaced all of that and all the code using the definitions were removed. https://github.com/aws/aws-lc/commit/913af96d029e0c80e8d573af6ddbbfd798ed98c5 removed the last legacy usage of it. The correct way to test breaking AWS-LC is outlined in FIPS.md: 1. Compile with `BORINGSSL_FIPS_BREAK_TESTS` defined 2. Run break-kat.go to break a certain CAST This also removes the note about fips_break_tests.h since that file doesn't exist anymore. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license. --- CMakeLists.txt | 3 --- crypto/fipsmodule/FIPS.md | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 51caa577a3..9f9ad495d2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -751,9 +751,6 @@ if(FIPS) endif () add_definitions(-DBORINGSSL_FIPS) - if(FIPS_BREAK_TEST) - add_definitions("-DBORINGSSL_FIPS_BREAK_${FIPS_BREAK_TEST}=1") - endif() # The FIPS integrity check does not work for ASan and MSan builds. if(NOT ASAN AND NOT MSAN) if(BUILD_SHARED_LIBS) diff --git a/crypto/fipsmodule/FIPS.md b/crypto/fipsmodule/FIPS.md index c671a2380a..5e45f7b74c 100644 --- a/crypto/fipsmodule/FIPS.md +++ b/crypto/fipsmodule/FIPS.md @@ -39,7 +39,7 @@ The AWS-LC-FIPS v2.0 module uses passive entropy by default and the specific ent ## Breaking known-answer and continuous tests -Each known-answer test (KAT) uses a unique, random input value. `util/fipstools/break-kat.go` contains a listing of those values and can be used to corrupt a given test in a binary. Since changes to the KAT input values will invalidate the integrity test, `BORINGSSL_FIPS_BREAK_TESTS` can be defined in `fips_break_tests.h` to disable it for the purposes of testing. +Each known-answer test (KAT) uses a unique, random input value. `util/fipstools/break-kat.go` contains a listing of those values and can be used to corrupt a given test in a binary. Since changes to the KAT input values will invalidate the integrity test, `BORINGSSL_FIPS_BREAK_TESTS` can be defined using CMake CMAKE_C_FLAGS to disable it for the purposes of testing. Some FIPS tests cannot be broken by replacing a known string in the binary. For those, when `BORINGSSL_FIPS_BREAK_TESTS` is defined, the environment variable `BORINGSSL_FIPS_BREAK_TEST` can be set to one of a number of values in order to break the corresponding test: From 3cf0777000dab8670595d4c1e0ab8b6fac182e81 Mon Sep 17 00:00:00 2001 From: Andrew Hopkins Date: Fri, 7 Mar 2025 15:00:49 -0800 Subject: [PATCH 7/9] Update EVP_PKEY ED keygen to use an internal function that can return the result of the PWCT (#2256) ### Description of changes: `ED25519_keypair` has always been void, this used to be okay because it was infallible. Now it can fail due to the PWCT failing. Usually if that happened the process would abort which is the default (and only approved) behavior of `AWS_LC_FIPS_failure`. However, if AWS-LC is built with the callback and that callback doesn't abort it is possible for `EVP_PKEY_keygen` to continue. Changes: * `EVP_PKEY_keygen` now detects this failure and return the error to the caller * `ED25519_keypair` doesn't increment the service indicator if the PWCT fails ### Testing: I updated the fips_callback_test to use the EVP API for ED and check the return value By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license. --- crypto/fips_callback_test.cc | 22 ++++++++++++------ crypto/fipsmodule/curve25519/curve25519.c | 28 +++++++++++++++++++---- crypto/fipsmodule/curve25519/internal.h | 4 ++++ crypto/fipsmodule/evp/p_ed25519.c | 13 +++++++---- tests/ci/run_fips_tests.sh | 3 ++- 5 files changed, 53 insertions(+), 17 deletions(-) diff --git a/crypto/fips_callback_test.cc b/crypto/fips_callback_test.cc index 1486780054..9091dbc7bb 100644 --- a/crypto/fips_callback_test.cc +++ b/crypto/fips_callback_test.cc @@ -106,7 +106,7 @@ TEST(FIPSCallback, PowerOnSelfTests) { uint8_t message[2]; uint8_t context[2]; uint8_t signature[ED25519_SIGNATURE_LEN]; - ED25519ph_sign(signature, message, sizeof(message), private_key, context, sizeof(context)); + EXPECT_TRUE(ED25519ph_sign(signature, message, sizeof(message), private_key, context, sizeof(context))); if (broken_kat == nullptr) { EXPECT_EQ(0, callback_call_count); @@ -133,12 +133,20 @@ TEST(FIPSCallback, PWCT) { EXPECT_TRUE(EC_KEY_generate_key_fips(key.get())); } - uint8_t public_key[ED25519_PUBLIC_KEY_LEN]; - uint8_t private_key[ED25519_PRIVATE_KEY_LEN]; - ED25519_keypair(public_key, private_key); + bssl::UniquePtr ed_ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, nullptr)); + ASSERT_TRUE(ed_ctx); + EXPECT_TRUE(EVP_PKEY_keygen_init(ed_ctx.get())); + EVP_PKEY *ed_key = nullptr; + EXPECT_TRUE(EVP_PKEY_keygen(ed_ctx.get(), &ed_key)); + if (broken_runtime_test != nullptr && strcmp(broken_runtime_test, "EDDSA_PWCT" ) == 0) { + EXPECT_FALSE(EVP_PKEY_keygen(ed_ctx.get(), &ed_key)); + } else { + EXPECT_TRUE(EVP_PKEY_keygen(ed_ctx.get(), &ed_key)); + } + EVP_PKEY_free(ed_key); bssl::UniquePtr ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_KEM, nullptr)); - EXPECT_TRUE(ctx); + ASSERT_TRUE(ctx); EXPECT_TRUE(EVP_PKEY_CTX_kem_set_params(ctx.get(), NID_MLKEM512)); EXPECT_TRUE(EVP_PKEY_keygen_init(ctx.get())); EVP_PKEY *raw = nullptr; @@ -153,8 +161,8 @@ TEST(FIPSCallback, PWCT) { bssl::UniquePtr dsa_ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_PQDSA, nullptr)); ASSERT_TRUE(dsa_ctx); - ASSERT_TRUE(EVP_PKEY_CTX_pqdsa_set_params(dsa_ctx.get(), NID_MLDSA44)); - ASSERT_TRUE(EVP_PKEY_keygen_init(dsa_ctx.get())); + EXPECT_TRUE(EVP_PKEY_CTX_pqdsa_set_params(dsa_ctx.get(), NID_MLDSA44)); + EXPECT_TRUE(EVP_PKEY_keygen_init(dsa_ctx.get())); if (broken_runtime_test != nullptr && strcmp(broken_runtime_test, "MLDSA_PWCT" ) == 0) { EXPECT_FALSE(EVP_PKEY_keygen(dsa_ctx.get(), &dsa_raw)); } else { diff --git a/crypto/fipsmodule/curve25519/curve25519.c b/crypto/fipsmodule/curve25519/curve25519.c index e1ef6d3c3c..4e38ee7187 100644 --- a/crypto/fipsmodule/curve25519/curve25519.c +++ b/crypto/fipsmodule/curve25519/curve25519.c @@ -32,6 +32,12 @@ #include "../cpucap/internal.h" #include "internal.h" +#if defined(NDEBUG) +#define CHECK(x) (void) (x) +#else +#define CHECK(x) assert(x) +#endif + const uint8_t RFC8032_DOM2_PREFIX[DOM2_PREFIX_SIZE] = { 'S', 'i', 'g', 'E', 'd', '2', '5', '5', '1', '9', ' ', 'n', 'o', ' ', 'E', 'd', '2', '5', '5', '1', '9', ' ', @@ -112,7 +118,7 @@ void ED25519_keypair_from_seed(uint8_t out_public_key[ED25519_PUBLIC_KEY_LEN], ED25519_PUBLIC_KEY_LEN); } -static void ed25519_keypair_pct(uint8_t public_key[ED25519_PUBLIC_KEY_LEN], +static int ed25519_keypair_pct(uint8_t public_key[ED25519_PUBLIC_KEY_LEN], uint8_t private_key[ED25519_PRIVATE_KEY_LEN]) { #if defined(AWSLC_FIPS) uint8_t msg[16] = {16}; @@ -121,17 +127,20 @@ static void ed25519_keypair_pct(uint8_t public_key[ED25519_PUBLIC_KEY_LEN], // This should never happen and static analysis will say that ED25519_sign_no_self_test // always returns 1 AWS_LC_FIPS_failure("Ed25519 keygen PCT failed"); + return 0; } if (boringssl_fips_break_test("EDDSA_PWCT")) { msg[0] = ~msg[0]; } if (ED25519_verify_no_self_test(msg, 16, out_sig, public_key) != 1) { AWS_LC_FIPS_failure("Ed25519 keygen PCT failed"); + return 0; } #endif + return 1; } -void ED25519_keypair(uint8_t out_public_key[ED25519_PUBLIC_KEY_LEN], +int ED25519_keypair_internal(uint8_t out_public_key[ED25519_PUBLIC_KEY_LEN], uint8_t out_private_key[ED25519_PRIVATE_KEY_LEN]) { // We have to avoid the self tests and digest function in ed25519_keypair_pct // from updating the service indicator. @@ -149,10 +158,21 @@ void ED25519_keypair(uint8_t out_public_key[ED25519_PUBLIC_KEY_LEN], ED25519_keypair_from_seed(out_public_key, out_private_key, seed); OPENSSL_cleanse(seed, ED25519_SEED_LEN); - ed25519_keypair_pct(out_public_key, out_private_key); + int result = ed25519_keypair_pct(out_public_key, out_private_key); FIPS_service_indicator_unlock_state(); - FIPS_service_indicator_update_state(); + if (result) { + FIPS_service_indicator_update_state(); + } + return result; +} + +void ED25519_keypair(uint8_t out_public_key[ED25519_PUBLIC_KEY_LEN], + uint8_t out_private_key[ED25519_PRIVATE_KEY_LEN]) { + // The existing public function is void, ED25519_keypair_internal can only + // fail if the PWCT fails and we're in a callback build where AWS_LC_FIPS_failure + // doesn't abort on FIPS failure. + CHECK(ED25519_keypair_internal(out_public_key, out_private_key)); } int ED25519_sign(uint8_t out_sig[ED25519_SIGNATURE_LEN], diff --git a/crypto/fipsmodule/curve25519/internal.h b/crypto/fipsmodule/curve25519/internal.h index e086a1c8a6..0a25754503 100644 --- a/crypto/fipsmodule/curve25519/internal.h +++ b/crypto/fipsmodule/curve25519/internal.h @@ -40,6 +40,10 @@ typedef enum { #define MAX_DOM2_SIZE \ (DOM2_PREFIX_SIZE + DOM2_F_SIZE + DOM2_C_SIZE + MAX_DOM2_CONTEXT_SIZE) +int ED25519_keypair_internal( + uint8_t out_public_key[ED25519_PUBLIC_KEY_LEN], + uint8_t out_private_key[ED25519_PRIVATE_KEY_LEN]); + int ed25519_sign_internal( ed25519_algorithm_t alg, uint8_t out_sig[ED25519_SIGNATURE_LEN], diff --git a/crypto/fipsmodule/evp/p_ed25519.c b/crypto/fipsmodule/evp/p_ed25519.c index e8b98b80ba..dc15893756 100644 --- a/crypto/fipsmodule/evp/p_ed25519.c +++ b/crypto/fipsmodule/evp/p_ed25519.c @@ -19,6 +19,7 @@ #include #include "internal.h" +#include "../curve25519/internal.h" // Ed25519 has no parameters to copy. @@ -33,12 +34,14 @@ static int pkey_ed25519_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { evp_pkey_set_method(pkey, &ed25519_asn1_meth); uint8_t pubkey_unused[32]; - ED25519_keypair(pubkey_unused, key->key); - key->has_private = 1; + int result = ED25519_keypair_internal(pubkey_unused, key->key); + if (result) { + key->has_private = 1; + OPENSSL_free(pkey->pkey.ptr); + pkey->pkey.ptr = key; + } - OPENSSL_free(pkey->pkey.ptr); - pkey->pkey.ptr = key; - return 1; + return result; } static int pkey_ed25519_sign_message(EVP_PKEY_CTX *ctx, uint8_t *sig, diff --git a/tests/ci/run_fips_tests.sh b/tests/ci/run_fips_tests.sh index 7cadc1f352..f27b3e0a2e 100755 --- a/tests/ci/run_fips_tests.sh +++ b/tests/ci/run_fips_tests.sh @@ -5,6 +5,7 @@ set -exo pipefail source tests/ci/common_posix_setup.sh +source tests/ci/gtest_util.sh function static_linux_supported() { if [[ ("$(uname -s)" == 'Linux'*) && (("$(uname -p)" == 'x86_64'*) || ("$(uname -p)" == 'aarch64'*)) ]]; then @@ -35,7 +36,7 @@ if static_linux_supported || static_openbsd_supported; then run_build -DFIPS=1 \ -DCMAKE_C_FLAGS="-DBORINGSSL_FIPS_BREAK_TESTS -DAWSLC_FIPS_FAILURE_CALLBACK" \ -DCMAKE_CXX_FLAGS="-DAWSLC_FIPS_FAILURE_CALLBACK" - ./test_build_dir/crypto/crypto_test + shard_gtest ./test_build_dir/crypto/crypto_test ./tests/ci/run_fips_callback_tests.sh echo "Testing AWS-LC static breakable release build" From 9b814f014cbea4a559aa3a4ba0e000ae501280ab Mon Sep 17 00:00:00 2001 From: Jake Massimo Date: Fri, 7 Mar 2025 15:30:57 -0800 Subject: [PATCH 8/9] Added ML-DSA to break-kat framework (#2253) ### Issues: Resolves #PQCrypto-130 ### Description of changes: - Added ML-DSA to the break-kat tool. ### Call-outs: As the break kat test modifies input to switch it all out for zeros, I had to change the `kMLDSASignPlaintext` in `self_check.c` to no longer be all zeros. As such the expected signature also has changed. We also are no longer able to re-use the signature from `ML-DSA-sign` in `ML-DSA-verify` as we want to break the verify KAT independently of the sign KAT. As such, `kMLDSAVerifySignature` and `kMLDSAVerifyPlaintext` have been added. ### Testing: Running break-kat and callback tests both pass. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license. --- crypto/fips_callback_test.cc | 10 + crypto/fipsmodule/self_check/self_check.c | 624 +++++++++++++++------- util/fipstools/break-kat.go | 2 + 3 files changed, 430 insertions(+), 206 deletions(-) diff --git a/crypto/fips_callback_test.cc b/crypto/fips_callback_test.cc index 9091dbc7bb..28a2cdee61 100644 --- a/crypto/fips_callback_test.cc +++ b/crypto/fips_callback_test.cc @@ -53,6 +53,8 @@ void AWS_LC_fips_failure_callback(const char* message) { {"ML-KEM-keyGen-encaps", {"ML-KEM-keyGen-encaps failed.\nExpected: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nCalculated: a7cc68f8d02110ca5720223b9e2a8987c8a24835a20dabcbefa430e74a85af80b9b74b74574c5e5f585459ca3610940f0b57b33344ceacccc135557b82f4968688a0168c1aa2940e5604482bf8b900a4343096446330cfee10917c0338181b7fe8d30f4816087d6299f225417f533ee40473894847bd45291367be6b1a7dee55bb21d60e3828552f4c8a6f3c54fc74cf67a614eeab002a076851879cef2218fdb3766123c2de32a269b6aa4661b69370314c004446f7258c40b2ea789f40ca023bbb1217c2c44b380c6e3194edd129d039218d9b75194a386d944acce7a9720ab026362004e95bf9229290b53613416082e82ba8a42a5ff14759f57712395706b307f7635ecee42317a48eb3b90683f3ab53d17c50f53c6cfb1c0cf59d6f2a981021428a7ac5edf13b26844d83c31d3608710e623aabb24b6c5b48baebc1b3078972589201b7a30bc09315612b067655bec403a69c89eb137c31157971098cb693ba4ae9ae40a8031cec92580bcc1b5ab3ecd1aa5f79aa2cd69249d138c8965a81c87a07eb59a4612e60658f4df028cef8af1b837e0ab0bfedb726904290d0bc41df6a67f7a4166609952439631960648e229a21f2a4d82abad3ec8135dc9bb43c703d3b33e437c9ef7bca91c3465676740125a15ad1707088b101b4273d3c4bf30181b4b2575de75ccfc13312a2a6bcebc477a9668e751629b569bfa20beca09800992c63f04b6b4a7df977a00131c2f8722e5138775235b517a709852167c1d415fdc7ad32f2aaca437e9cc6b248d9ca7c65b405e68d24e81b8688caa22b3cf5c9b147f0cc27e667a80b83ccbb4f4161a5ffd0194b1b5720e68ea0f59997f26740972d2c8124d7a6ad8327c2075a3f76b968d2aaad19c00697599e0be49fa6d65b4088b0be692dcda028095852a0d7205e4417409c0317780305a878fb582963b6953f6b8f0880b050178301d659be3a4db7e0bf2587129164178f32707d40392d85713dea82913999aa6c35aa94b3547abe40e2b0ba82b5b78319182a5a47d173176ba6fa3a4d70a8130b310743fa8aaae314381c9b7f49991f19a4ff8369638de380b5d828b7b5fcfdd91fe68efe16d4cd9eed66d65c1d2d8caf5af4a692\n", "ML-KEM self tests failed"}}, {"ML-KEM-encapsulate-ciphertext", {"ML-KEM-encapsulate-ciphertext failed.\nExpected: 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nCalculated: 431a4f1b2d2c6c00f1690bbe482541ef3d563774daff83207f96de7e5e4a59d5d936d9443ad422e645793e7a60a9b0a76cd672d20c69b82a5563df52d96f9a6cdfc56fbd4fd8d5a8afeb2a09d92ec854094794b4ed2db381f04c68439608aa9902a4d1689e2eb1e5f07a4a1c709262d7c2ff2f81f6eeaab2a86a41ba210eb1bf8e75febccd1a15b4d7a7b60257c89d00bd81d39fcb8d1ce3278102595dd652f7fb7d5584874f3327b174043b350ebd4d41fe08bd0e854d41cbb027c481da64dc6151b88dececcf022ddac2e22736c147e0773294231c0589967154c526b0b7cdd59568eeff5749a40cb100c60c6480897655d96e9f64d61684c0b3150646732c19409fe565540a31894703cf0179cae85bc8c1a5732649836e48e676405b9591b65ba25f9b489b9e5772aa1ed5a00143cb9f5449fd013457a3c13874cb58c75b52c9b6a9ae495ccb504a89cb5f145695b921632fb85b0316b30d4ad17fef0862d6b1e6ca6a611c8a6a7234b4362c5ca0ad9f7697687798cf624dc9f35fbb376e09953156532a9033709df755b46cc6d83de3a111e19a76b361e0ef14c91db8d91c6c6d9e3e46f42291fd6cbf5cfd122716fb0675698e602ab39ee98e0d8145eebaaa9374f5b3bb0df4d0fd83a40e0d25038c39e9bee01cf79c86f3086158d031d5c5e86bc7e7eb16e622505f2888213884c0b5252289b11fce5bfeebfbef0a32ceaf9c14c6250090028463db6f8d19684f541108fe934d88e7ef5cce9daebb32700b9397691a684298c9bf1b7c22d1bcec3fcacfbb17f2ed2b98b85e6a8fe2482996b5e099e9d0211cb9412614de87dc18d23613ed7f6c29cc37b727116dd901c2817938c29fcd026089336addc09eca90de9a25a6374fee86bcdd06ae3daaf0b1bc5b3b2790d4d9f759bef8ac743612a2bbf6e45de8b22efa61226625d4c39f346b844c5ebec5355866c00b726cc1640cb237c34a20a7c603d251f46e6b3b0fa71b3276835e3e9da5b9485e789614af49f1e9504db2528631fbe1cd7dbee85164e4c099a27a4583e9247d078f8830b46874c1b010bf3cd90eb0774961f239ba\n", "ML-KEM self tests failed"}}, {"ML-KEM-encapsulate-shared-secret", {"ML-KEM-encapsulate-shared-secret failed.\nExpected: 0000000000000000000000000000000000000000000000000000000000000000\nCalculated: a772df2de250ac7d896bbb820b57f2ae05f9a412ab55baa421d4af6dac62662a\n", "ML-KEM self tests failed"}}, + {"ML-DSA-sign", {"ML-DSA-sign failed.\nExpected: 346980e51914722cb3dc402dcac9fa9acba9f189e6e12cba7a15181bf95f8830e3b0271b4a9f84d45a1a29c18d15ea254e9f5e6dbd0f12ad8a7008df067e931469a9c35759736677456a901cbfc79bf7351f5585b7a2590490839e3013d31037a08a1cd3501e4b658230f0318495c498d70440d578c7f7bd61c7a1a3da315c4030698bc70eb331bbb83bab5a6b63338f113155845d97389d294e1d3b77658c1e24a438f9cdf13b1e011c2e5b25dcc218a975765ba79e631912b0ad10cc8bbd90e7ba258a702a9b5e6d72f578b5a942b9917a3989ae8ae0b98cde128b529589c2fbbaa82a817ef2b3d9169788387c612e2488b62ab9664d2e06b3f22de1eb091e0e89afe5b090e1b81d6867b2bea7c019079b293d8b105822f0cb34fdc03e1210062e4e1e280ce3b58d87f843de43082408220390676b07e6ae5c1b6fa77d571249a37efd41e94daf2d96a54042650f77aaab3c43ec5afea08e55bb494952aa40b5095e7c1b98d8104ab07e7dbfc5f6f6826761e685d06a3a00f38841a2ba8d2ccde1145cd4b0643d953d8fd4c4859bb72f338b9a1c038f88cefb5b33f89078f7ed8fa050534b6197ccd244b3bbd7066f6c4bbe7482ecebad203e8079599d6adcc25efc151e3be9c0d7435ac1cb3a572381da123a6798cf21d19835f9b999d09c0b0a09f86a9cf87f2ed5133e36ea6d6986182796612bd06191c9e494050953141da174503c9c874bf07a3b64994583c3bab1aa90e04331200f86ce5f705fe467a4741b0bd57c34b8d66626c42d72f77439f5bcb4ed2e3f197270a93efe68f7b2a30d6ebd9fa2297f59773e3d8e81cec9ea9defd1b44309759d0bfb0f43aa29388db988f2be645ffb3de9edc1181e934f1496ceec5e313fb9aaad37dd6a8be09c7c7fd263c2c95c87d5f884bb75ead677b3a0e4bcc8bec4f99ed3ee13fc891b6cc5869ac85d05753c4cba0b32911aefab1767a7d07c061af805c176733490f0e2010bebb18eb8c61cec3920a33866c2ff8197b0615dae2d8e3b6412afd06875f19f5bd70ad478b89a7f3c7e0ed33a12f095bb0c2f06ad0c8f43ba82224b68c6c9cec9923c2f6ccd0995e5015d7f9e73074262de21ca59697136fd99923d057be5008b3bb018a559439bba5e33bbe25b75ad95fc9ed47c2a93ce1e4af30f0f6811519d2af232f3ba0010a7bf23284ebed67b1a661fcd3e4dad4fed42330a5f8cb16772943bd93fb25ce77c0680a4b79224ac4aff9aedf95d04f92ae2917fdd97144456a38e476bf86fb57f58ae611ac6cd7b2abd908e78d5312ae72dc9f7cb999f3c42bef6271edb57f4c3d9ac1ea2d93cc0073c65666b0f5a71cdbfff5e8180804b6e8c3653323589939fa7747a68ea9f37272f4cb9bbcc0d529431d866e929aad9cf39cc8a39ca09ba1520d7a885e79c76efe5fead4e37987ce2610f025bee4beef225e7d9c7851317eb7991e46d68ded6de12a848870b73328732c060dfdab291395b8cce4dbfa9f7fd1e2d2c3deed6fe1bed9cc25a3629b472d8e484f07df8f090849d78d222e068afc9e99d3cf6a615fdeb778395a4bbf0535c2d97257f012a29e6fa0390446772ca1615852023d6155502a012b282c408c71c2f70331bfec46b09136d4fd495b051422bd1ea4787ef3c8b0068a0736f8de8264c85b84730366aca64924f231eb169fc13205cb4f1eae71898642a5bfaf2c81f7d06aa7e5c98852e553afeaf383554fa9eef32b2bf82451ae7c405f12530cb4523d48eb43d72436d97cdd01f7284e6a8cbeb6d67db50b43fa3e272914383ac591203ba489ca2282e426b05dbab35e77c636e13ceb2725c911fefc3d280d1caa74b356f183d7091eb5905f2b615de6191215785f6e2e1ba0700b1f9ed749bc5265ac318a40c99c68cf901fc81f4859a91e4d248cecae1b89a7b245d1df9db7431292765d23f4c651b3212c3e2ee159bfca1d7b5aee74e539f23363c11c80f079f3e627b5c6bf097c8f928299f28329eb969f64c9aad1089e4eb3957a9e2a2a3dc6a1ddb84b6c51560e6cf26dd9868f5c7bcb1071cdd665492aead80f63ed22a23857c233be5af0d172c7650babc6ead9d0c683ca0b3924ac06cdead8a70d6fa996baef9976023f08b7b05b7824610ebbf9b0e9e18a06246706af5c0167accda3db0fe475be6775feed73096f4b4fa295720a6ac64f13d9f8457f2f394e019a608a5c2f918f7e53f81a37766fd3f0a9c83d0a9226dad2837c70fa8c2ca7489bc0efe37d54798b386ebe580007bccba84b103be531eff0f9d978aa0b3306953573ffd0c37c63a637cd7d2425b6fa3850cc7aab3c6e8758d4dd29939dba4885f9573e21b381edca580aaed49ae88879376d38986936cf5b3a33d52a32a372607984c550ed434bb9b0d71e4456b304f359b8db113ad14bcf53e4e276d5f562a90f3eaceab033bfe383509a5c5e960a49437b97ea6989b06f686bf50c7e1373324d89747e04b36afcbf0e407dc4a8a60ce01d09ed58f2d4a0b99d9048f2efc75c12ff53b7fe2f26584d60aee52bc1f484d0f99d9e86b2c882c5be7c783f6b9c8d35a71cf38fe1b036b381f5e72ed9928ce656fd898c2bf4ecc351723527d692a65c5545c2180e64f1520b942c6c39c83a1012e5e06af35c07cfd3222a14b6ac33f3d7b5c3280617c62d381fdf9da7bfc04b5632e2f027d2261a557138a84b57c527422be2de24bc43b1c2199a57e00e831cc4cb82d8310f53d2c7dfa6b293a0e2d815ee3934c5122860fee423131b4bf2cb66692c1dd0da9a4cd6df11ecc17e64ac6bca5b6c945f2a962dd0d7e26c895086572e9cbf37f403d39d7ffa2b35485d5cfa62a99c565aa8c1de312e8d795fa344bc82372337f4e41aea7b2e6e989cd38f2005ab32d8c35afbcae9e0ed2d03c1f9f0af429b0d8e8d299d766dc0700508e986b3c13a38f8c03880b1833dab4ae6fac36db1b872e26685bc6a057f306b12fd79c6619c2747ed786d9a3e69eaadc85b4dd4cdc8f6b107fb66ca034f06539e9b26e18ffd5fc03b60d6af816564a0cf05f66473f2ff747e9953c224b40aeff88e860d0077e850b3a6e054429ec0d83d05ccd71d52412553820156bbd8b888c30b310ae265b8bb14d33e99e4822584ef8abca95292bccd681def52c680bf59c94ce990ebfea6d7441dd3c131fd90c13e5d1ef2ae1f07076669e50c9da58a1660636abd368e35452c508e24255fb8d48a908959d661c69da2e71c87ab250d649c02e52606495136321692e5ed48a3ba3f534d05606b796be2c2c977d8307def546d5a4e09688655c082a378f99a6afc8def4fe151f2d32333a687b7f8fa3a6a7aab7bcc2eff40a24667076829a9fa6bed6dce6ebf2354b50a0bfdffa000000000000000000000000000000000000000000000000000000000b1e2d34\nCalculated: 4efb3abe8ac47b40d4b1d59961ee658ba7c2a21236e0c027966eac19b0b415c9824af94955233a6a321ba66370bf1313bec01bebce2a7c6391833fef3ecd58b213bbb723dedd0c04b33644a5a4494b47528c616fbf4075acf04fb5d853badaa25d240651056d3c3cfdafbaea8f0996234ccdbc033f3ed29d2bcb8610bdd728561bde8a4cd7a0361b630de71ae10db50d2caf61dc393658c8c4fe822a0b8b2d17ebbc1f9bc5947bed10ee69ffb4c66f59af4da89efd0cf5c722f6687b9c1d528ee3b8b675e01e9eef5093590539f9768260bcc8fdc0b7f0d496b1d981260fda2f6caecd7025a769035116a9db27a04c4d758943a9312b77b9d45c386dc5250b1820fe443b07f3ef6ddba67e09efee9c59016bd076f12a2cde6e386ab690bd417bf123c5282ea93a5fe86a0d93fa6b3ec160df642f81f8778225138cd2f77a013cc67273fe2a48189d360ccde080c2292e2100ac815bdb33bb50c56feb4963ddef80bc2dd3e4e069af8dda5406455b69913e4ffc1fab0cf3dcf47a06de643b087cc92c0de1bddc619b883a8e77d383bc70f698d372e27e0e8dea3a3b261b8eae498c2514e405cd9c2cdb39e92f16f571e287c9d1d37abf1dbf986cb13cf8f4d619b13945c1b4a5372e9855bfc23a36953de9c0dadca15067430dab9af898b03e8c4e8ff0a72ad936aae0e20948ab9b5dba6dabfcb5466fb330fb6f602b2821eaf949c6c4e05fb62fa0654c02980456108eac4ac7347c822f467086aac01c3851b061bc8c604567483b0443df4ba14cc2cc67198a907758ea560ad486adcc018d48286e9a7c4b268b2785bd7fd49e3b5320b89ff6378b14440c9c5b71c59ffc537d52b05fa7bd296ecff0e88501a8a4b2785b8a60fa74186f6267edaa0163db723ebd3d690c63f2883052e1a128cd7cee543921ec78c1189de754f8627e35e7a3430611d3a378879d35569bb4f749854e557deffd97c652c9df22e31f1203ae854f3b7684da49af61a467ec7f8e1fa5eb4fea00bdfda9df4f071df8d51e6725e9cf25c882418252b2c3ae00aa1b2cbc5275418daaa96597b48e63f3df98bec788651003a95041ebf02f62c95981adca03a1a1832eb9b6d1425b436214d1009b2ce5388a573c4160e8afb9b1cbcdbc0d16c91591975ccec4b1131bcce98eac2391114f480b6c75af4d07d549d2a17ff3866335809e7b9b2665715d10fe01ea4342f5b6200d9b8561324d11c7d92667fce0eea730da5dea93348cc684f6ac35c690f17d8d0fc99cf70f5d74b77a08f9b8afd1a6ab950f6dab880f88a39a16779141443e79a4099a90ff6ec41270d52a79f4cd0a66b7bb7d92ed00759a9da48a171bc2fd6d1de3a9141f6c614ca97e9696a44ae326d0ca1d091aabb030a8824675239aead6cdbf6b9de0c371c925f4c412249d31200103cf67ec76131ad2bfbe7bf30a31de8186600d11bd35730a6996cac10ec1224b71c12bcf1ff85a2ac2f9390adad754e0ebb1f6153b8cf2fc06648acf2610db11d0a16e8d25dc79979e9de6b2dc236111f85f76e9df2499d5193d3daf13102dd9e43eb51a166ffd9823ff8d88e1fdbdcfcbea1771a1202d97f4b66c1a8d910cb66f5f405f8c786b79e9df8e1df64f871fbdd95ca3f8656b704cee55f22b299d6466ef5a0544abe9fb9ef8e9458a3fb75f328c8a36afa33f2ba6a80dfd34cf592e3ca2174783456acdcfb5589ccd362e09b0e9d3106bc8fd9103eb3dcce8269ffaab78884c3a95570f0b67d863c56f6895a7b6e0409e51c4d42047026df47306bf459283b4d63f4ae7a5547c1c478abea835378f0f5efab665c8179008b71fc16ba3d50c6f17a25e12859cb2d4876fe495fe21b792034236db254024de98e41f439895dbb08a7da78677d0d07154949d78c7669ea169fa1add0d9bc2d379323c2439bf1fbb144b7127fced842b3167d99d382aa85c7b350b8480b222349179feba54bd5f73e55ac7000bdf583840c0fde5af27fa3ca573c3f8eeca5b9e635b008bec30bf87f64d4173def58f3a8f2c32aaca6e2fb8758fa647b005c7a74053b018cbd8429d01fddfdd25e38ffe84ad6ff7ff091b6c0b8340d5cae337ca68e8996ac0afb1e1f6dfe0a3290b6c95dcb985d1b5b4cebe2ca6609dfe046866d710e7d83867bb6742609dc8b6070488230eab2c13a20afb672a4e662fee88c681075c0d7ee6a748bcf35f11785e4121de68b22c0a54a38fd56e56e51858c2628411d220333330a45080fa68c4072370b4bc4034850340ccc15825b45f235497a4f6f514a6d39484157d06605e81b12359982dadc9b8bc6aa762f02e1e7e219d741390381fa927cb35373c283eb77534ed9bf634ea35a113f051fdd8527bd4e0650b3110ed0a6ef09f730ab2f947d234e6bc079d577280432ca56b57a87443a57191b7b9d793adda1f9c082fa6ca38ba9847cbe7b5bc239c83b806d60f2b74c9a5f347583f2a93edf990b337e359b8e259763862df5c74fd733c2993e31d17da5343df7b58f859f1e7ab3f056d0db7bdf1259530c4bf4fc723554de7dcb01f3420fc6bec4d3c1878d428ba5e93ff2ad17ec72229b3f0b24718efaabd27d2caf64eb58678a0e5b5f51e4d1c3d5f2f72b15c13ea13f987203e843f6c6b3ef3dffc6bc351724ee023818c950774946f52ff022d605bd75b1270dc940f31f8c073ed8a950e7f973d2b4793a5b8ec4ad9ae8771d5ae877794b7c82291b450e877d66fcb998bfda8edd33508d295610b03ff7b7f02576ea9583da2f0b617092231d42db7d6add1dfd605c85293c48198c7207f60ede3dd91be38ebe2864f51f555dcbd7e8aaa114e1e7372213aeba4671cf9432a7ebe7c3a6c54f7b4b7b62efe4f4bc02799ba3b177d1382307d95b71e53277a1401ef0ce299b0267b16d12a21eb0e8b1b1d45036b0950cde660bb21d5a6f82fb45378c81315380e42d39a95fb97beb9779d1d36f3b42731ddf5b4a1a1ae2a9bfdd84a5771bdcc00b615d13615052aea4acc1885589c4019723832078440ae9aeee415b1fc9fceed45d403f88162104b257695574eaa60ec889b5651759616fc2224fca7376b138a029f932c6b389678bb697612353365835984ae76c74d13dab17b8842b507d4240ba181693c9fc803015ebfc01ba183bcfe4f6b7a0333259fb939219c1d2fc0891aac8d0f1e0d7e2f5a1ef2a3b3ed3e1cb2145f16f1147f4e889cb0c7a72b42fbb5e842c35c7354856789fc6c8ae4cd9b2d4ea46546d59cfce3dc17ebeda897fc4d4d81b4cfaab627e0e2172bd4b6ec43268e0718e620fa269568909397b5c2c5f6f7f9fb28446d707599b5c0c1d2d7dffcfd010709163b4c4f5563797a888b949aadc4c7d4f316365b95abdce4f5f800000000000000000000000000000000000000000000000000000b192d36\n", "ML-DSA self tests failed"}}, + {"ML-DSA-verify", {"ML-DSA-verify failed", "ML-DSA self tests failed"}}, {"HKDF-SHA-256", {"HKDF-SHA-256 KAT failed.\nExpected: 000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nCalculated: ca5e6410e7a52332fe0ab3601212a7d3dbdf55a162af42a5daf38b94f24523477e880dd711508684cc21\n", "Power on self test failed"}}, {"KBKDF", {"KBKDF-CTR-HMAC-SHA-256 KAT failed.\nExpected: 10621342bfb0fd40046c0e29f2cfdbf0\nCalculated: 606060902f7c6632bcde3a67f5818c48\n", "Power on self test failed"}}, {"PBKDF2", {"PBKDF2 KAT failed.\nExpected: c6ac0779e4a117c922287f5e10e7ee6ba74d8b19519b4cc738\nCalculated: e442f1807d5fc9b466badcdfd3806fed7fa50da9a6f5729117\n", "Power on self test failed"}}, @@ -108,6 +110,14 @@ TEST(FIPSCallback, PowerOnSelfTests) { uint8_t signature[ED25519_SIGNATURE_LEN]; EXPECT_TRUE(ED25519ph_sign(signature, message, sizeof(message), private_key, context, sizeof(context))); + EVP_PKEY *dsa_raw = NULL; + bssl::UniquePtr dsa_ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_PQDSA, nullptr)); + ASSERT_TRUE(dsa_ctx); + ASSERT_TRUE(EVP_PKEY_CTX_pqdsa_set_params(dsa_ctx.get(), NID_MLDSA44)); + ASSERT_TRUE(EVP_PKEY_keygen_init(dsa_ctx.get())); + ASSERT_TRUE(EVP_PKEY_keygen(dsa_ctx.get(), &dsa_raw)); + EVP_PKEY_free(dsa_raw); + if (broken_kat == nullptr) { EXPECT_EQ(0, callback_call_count); } else { diff --git a/crypto/fipsmodule/self_check/self_check.c b/crypto/fipsmodule/self_check/self_check.c index e2ec45631f..759b2c9ade 100644 --- a/crypto/fipsmodule/self_check/self_check.c +++ b/crypto/fipsmodule/self_check/self_check.c @@ -1846,11 +1846,17 @@ static int boringssl_self_test_ml_dsa(void) { }; static const uint8_t kMLDSASignPlaintext[32] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x4a, 0x41, 0x4b, 0x45, 0x20, 0x4d, 0x41, 0x53, 0x53, 0x49, 0x4d, 0x4f, + 0x20, 0x41, 0x57, 0x53, 0x32, 0x30, 0x32, 0x35, 0x2e, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, }; + static const uint8_t kMLDSAVerifyPlaintext[32] = { + 0x83, 0xf2, 0x1a, 0xc4, 0xb5, 0x9e, 0x7d, 0x2f, 0x48, 0xe6, 0x95, 0xd3, + 0x0c, 0x5b, 0xa1, 0x8d, 0x3f, 0x67, 0xb9, 0x14, 0x92, 0xc8, 0x4e, 0x76, + 0xf5, 0x21, 0xaa, 0x54, 0x89, 0x36, 0xdc, 0xeb, +}; + // ISO/IEC 19790:2012 Section 7.10.3.3 15. page 84 Requires the randomization // parameter rnd be fixed for the “hedged” algorithms (e.g., all zeros). static const uint8_t kMLDSASigGenSeed[MLDSA44_SIGNATURE_SEED_BYTES] = { @@ -1860,208 +1866,413 @@ static int boringssl_self_test_ml_dsa(void) { }; static const uint8_t kMLDSASignSignature[MLDSA44_SIGNATURE_BYTES] = { - 0x4e, 0xfb, 0x3a, 0xbe, 0x8a, 0xc4, 0x7b, 0x40, 0xd4, 0xb1, 0xd5, 0x99, - 0x61, 0xee, 0x65, 0x8b, 0xa7, 0xc2, 0xa2, 0x12, 0x36, 0xe0, 0xc0, 0x27, - 0x96, 0x6e, 0xac, 0x19, 0xb0, 0xb4, 0x15, 0xc9, 0x82, 0x4a, 0xf9, 0x49, - 0x55, 0x23, 0x3a, 0x6a, 0x32, 0x1b, 0xa6, 0x63, 0x70, 0xbf, 0x13, 0x13, - 0xbe, 0xc0, 0x1b, 0xeb, 0xce, 0x2a, 0x7c, 0x63, 0x91, 0x83, 0x3f, 0xef, - 0x3e, 0xcd, 0x58, 0xb2, 0x13, 0xbb, 0xb7, 0x23, 0xde, 0xdd, 0x0c, 0x04, - 0xb3, 0x36, 0x44, 0xa5, 0xa4, 0x49, 0x4b, 0x47, 0x52, 0x8c, 0x61, 0x6f, - 0xbf, 0x40, 0x75, 0xac, 0xf0, 0x4f, 0xb5, 0xd8, 0x53, 0xba, 0xda, 0xa2, - 0x5d, 0x24, 0x06, 0x51, 0x05, 0x6d, 0x3c, 0x3c, 0xfd, 0xaf, 0xba, 0xea, - 0x8f, 0x09, 0x96, 0x23, 0x4c, 0xcd, 0xbc, 0x03, 0x3f, 0x3e, 0xd2, 0x9d, - 0x2b, 0xcb, 0x86, 0x10, 0xbd, 0xd7, 0x28, 0x56, 0x1b, 0xde, 0x8a, 0x4c, - 0xd7, 0xa0, 0x36, 0x1b, 0x63, 0x0d, 0xe7, 0x1a, 0xe1, 0x0d, 0xb5, 0x0d, - 0x2c, 0xaf, 0x61, 0xdc, 0x39, 0x36, 0x58, 0xc8, 0xc4, 0xfe, 0x82, 0x2a, - 0x0b, 0x8b, 0x2d, 0x17, 0xeb, 0xbc, 0x1f, 0x9b, 0xc5, 0x94, 0x7b, 0xed, - 0x10, 0xee, 0x69, 0xff, 0xb4, 0xc6, 0x6f, 0x59, 0xaf, 0x4d, 0xa8, 0x9e, - 0xfd, 0x0c, 0xf5, 0xc7, 0x22, 0xf6, 0x68, 0x7b, 0x9c, 0x1d, 0x52, 0x8e, - 0xe3, 0xb8, 0xb6, 0x75, 0xe0, 0x1e, 0x9e, 0xef, 0x50, 0x93, 0x59, 0x05, - 0x39, 0xf9, 0x76, 0x82, 0x60, 0xbc, 0xc8, 0xfd, 0xc0, 0xb7, 0xf0, 0xd4, - 0x96, 0xb1, 0xd9, 0x81, 0x26, 0x0f, 0xda, 0x2f, 0x6c, 0xae, 0xcd, 0x70, - 0x25, 0xa7, 0x69, 0x03, 0x51, 0x16, 0xa9, 0xdb, 0x27, 0xa0, 0x4c, 0x4d, - 0x75, 0x89, 0x43, 0xa9, 0x31, 0x2b, 0x77, 0xb9, 0xd4, 0x5c, 0x38, 0x6d, - 0xc5, 0x25, 0x0b, 0x18, 0x20, 0xfe, 0x44, 0x3b, 0x07, 0xf3, 0xef, 0x6d, - 0xdb, 0xa6, 0x7e, 0x09, 0xef, 0xee, 0x9c, 0x59, 0x01, 0x6b, 0xd0, 0x76, - 0xf1, 0x2a, 0x2c, 0xde, 0x6e, 0x38, 0x6a, 0xb6, 0x90, 0xbd, 0x41, 0x7b, - 0xf1, 0x23, 0xc5, 0x28, 0x2e, 0xa9, 0x3a, 0x5f, 0xe8, 0x6a, 0x0d, 0x93, - 0xfa, 0x6b, 0x3e, 0xc1, 0x60, 0xdf, 0x64, 0x2f, 0x81, 0xf8, 0x77, 0x82, - 0x25, 0x13, 0x8c, 0xd2, 0xf7, 0x7a, 0x01, 0x3c, 0xc6, 0x72, 0x73, 0xfe, - 0x2a, 0x48, 0x18, 0x9d, 0x36, 0x0c, 0xcd, 0xe0, 0x80, 0xc2, 0x29, 0x2e, - 0x21, 0x00, 0xac, 0x81, 0x5b, 0xdb, 0x33, 0xbb, 0x50, 0xc5, 0x6f, 0xeb, - 0x49, 0x63, 0xdd, 0xef, 0x80, 0xbc, 0x2d, 0xd3, 0xe4, 0xe0, 0x69, 0xaf, - 0x8d, 0xda, 0x54, 0x06, 0x45, 0x5b, 0x69, 0x91, 0x3e, 0x4f, 0xfc, 0x1f, - 0xab, 0x0c, 0xf3, 0xdc, 0xf4, 0x7a, 0x06, 0xde, 0x64, 0x3b, 0x08, 0x7c, - 0xc9, 0x2c, 0x0d, 0xe1, 0xbd, 0xdc, 0x61, 0x9b, 0x88, 0x3a, 0x8e, 0x77, - 0xd3, 0x83, 0xbc, 0x70, 0xf6, 0x98, 0xd3, 0x72, 0xe2, 0x7e, 0x0e, 0x8d, - 0xea, 0x3a, 0x3b, 0x26, 0x1b, 0x8e, 0xae, 0x49, 0x8c, 0x25, 0x14, 0xe4, - 0x05, 0xcd, 0x9c, 0x2c, 0xdb, 0x39, 0xe9, 0x2f, 0x16, 0xf5, 0x71, 0xe2, - 0x87, 0xc9, 0xd1, 0xd3, 0x7a, 0xbf, 0x1d, 0xbf, 0x98, 0x6c, 0xb1, 0x3c, - 0xf8, 0xf4, 0xd6, 0x19, 0xb1, 0x39, 0x45, 0xc1, 0xb4, 0xa5, 0x37, 0x2e, - 0x98, 0x55, 0xbf, 0xc2, 0x3a, 0x36, 0x95, 0x3d, 0xe9, 0xc0, 0xda, 0xdc, - 0xa1, 0x50, 0x67, 0x43, 0x0d, 0xab, 0x9a, 0xf8, 0x98, 0xb0, 0x3e, 0x8c, - 0x4e, 0x8f, 0xf0, 0xa7, 0x2a, 0xd9, 0x36, 0xaa, 0xe0, 0xe2, 0x09, 0x48, - 0xab, 0x9b, 0x5d, 0xba, 0x6d, 0xab, 0xfc, 0xb5, 0x46, 0x6f, 0xb3, 0x30, - 0xfb, 0x6f, 0x60, 0x2b, 0x28, 0x21, 0xea, 0xf9, 0x49, 0xc6, 0xc4, 0xe0, - 0x5f, 0xb6, 0x2f, 0xa0, 0x65, 0x4c, 0x02, 0x98, 0x04, 0x56, 0x10, 0x8e, - 0xac, 0x4a, 0xc7, 0x34, 0x7c, 0x82, 0x2f, 0x46, 0x70, 0x86, 0xaa, 0xc0, - 0x1c, 0x38, 0x51, 0xb0, 0x61, 0xbc, 0x8c, 0x60, 0x45, 0x67, 0x48, 0x3b, - 0x04, 0x43, 0xdf, 0x4b, 0xa1, 0x4c, 0xc2, 0xcc, 0x67, 0x19, 0x8a, 0x90, - 0x77, 0x58, 0xea, 0x56, 0x0a, 0xd4, 0x86, 0xad, 0xcc, 0x01, 0x8d, 0x48, - 0x28, 0x6e, 0x9a, 0x7c, 0x4b, 0x26, 0x8b, 0x27, 0x85, 0xbd, 0x7f, 0xd4, - 0x9e, 0x3b, 0x53, 0x20, 0xb8, 0x9f, 0xf6, 0x37, 0x8b, 0x14, 0x44, 0x0c, - 0x9c, 0x5b, 0x71, 0xc5, 0x9f, 0xfc, 0x53, 0x7d, 0x52, 0xb0, 0x5f, 0xa7, - 0xbd, 0x29, 0x6e, 0xcf, 0xf0, 0xe8, 0x85, 0x01, 0xa8, 0xa4, 0xb2, 0x78, - 0x5b, 0x8a, 0x60, 0xfa, 0x74, 0x18, 0x6f, 0x62, 0x67, 0xed, 0xaa, 0x01, - 0x63, 0xdb, 0x72, 0x3e, 0xbd, 0x3d, 0x69, 0x0c, 0x63, 0xf2, 0x88, 0x30, - 0x52, 0xe1, 0xa1, 0x28, 0xcd, 0x7c, 0xee, 0x54, 0x39, 0x21, 0xec, 0x78, - 0xc1, 0x18, 0x9d, 0xe7, 0x54, 0xf8, 0x62, 0x7e, 0x35, 0xe7, 0xa3, 0x43, - 0x06, 0x11, 0xd3, 0xa3, 0x78, 0x87, 0x9d, 0x35, 0x56, 0x9b, 0xb4, 0xf7, - 0x49, 0x85, 0x4e, 0x55, 0x7d, 0xef, 0xfd, 0x97, 0xc6, 0x52, 0xc9, 0xdf, - 0x22, 0xe3, 0x1f, 0x12, 0x03, 0xae, 0x85, 0x4f, 0x3b, 0x76, 0x84, 0xda, - 0x49, 0xaf, 0x61, 0xa4, 0x67, 0xec, 0x7f, 0x8e, 0x1f, 0xa5, 0xeb, 0x4f, - 0xea, 0x00, 0xbd, 0xfd, 0xa9, 0xdf, 0x4f, 0x07, 0x1d, 0xf8, 0xd5, 0x1e, - 0x67, 0x25, 0xe9, 0xcf, 0x25, 0xc8, 0x82, 0x41, 0x82, 0x52, 0xb2, 0xc3, - 0xae, 0x00, 0xaa, 0x1b, 0x2c, 0xbc, 0x52, 0x75, 0x41, 0x8d, 0xaa, 0xa9, - 0x65, 0x97, 0xb4, 0x8e, 0x63, 0xf3, 0xdf, 0x98, 0xbe, 0xc7, 0x88, 0x65, - 0x10, 0x03, 0xa9, 0x50, 0x41, 0xeb, 0xf0, 0x2f, 0x62, 0xc9, 0x59, 0x81, - 0xad, 0xca, 0x03, 0xa1, 0xa1, 0x83, 0x2e, 0xb9, 0xb6, 0xd1, 0x42, 0x5b, - 0x43, 0x62, 0x14, 0xd1, 0x00, 0x9b, 0x2c, 0xe5, 0x38, 0x8a, 0x57, 0x3c, - 0x41, 0x60, 0xe8, 0xaf, 0xb9, 0xb1, 0xcb, 0xcd, 0xbc, 0x0d, 0x16, 0xc9, - 0x15, 0x91, 0x97, 0x5c, 0xce, 0xc4, 0xb1, 0x13, 0x1b, 0xcc, 0xe9, 0x8e, - 0xac, 0x23, 0x91, 0x11, 0x4f, 0x48, 0x0b, 0x6c, 0x75, 0xaf, 0x4d, 0x07, - 0xd5, 0x49, 0xd2, 0xa1, 0x7f, 0xf3, 0x86, 0x63, 0x35, 0x80, 0x9e, 0x7b, - 0x9b, 0x26, 0x65, 0x71, 0x5d, 0x10, 0xfe, 0x01, 0xea, 0x43, 0x42, 0xf5, - 0xb6, 0x20, 0x0d, 0x9b, 0x85, 0x61, 0x32, 0x4d, 0x11, 0xc7, 0xd9, 0x26, - 0x67, 0xfc, 0xe0, 0xee, 0xa7, 0x30, 0xda, 0x5d, 0xea, 0x93, 0x34, 0x8c, - 0xc6, 0x84, 0xf6, 0xac, 0x35, 0xc6, 0x90, 0xf1, 0x7d, 0x8d, 0x0f, 0xc9, - 0x9c, 0xf7, 0x0f, 0x5d, 0x74, 0xb7, 0x7a, 0x08, 0xf9, 0xb8, 0xaf, 0xd1, - 0xa6, 0xab, 0x95, 0x0f, 0x6d, 0xab, 0x88, 0x0f, 0x88, 0xa3, 0x9a, 0x16, - 0x77, 0x91, 0x41, 0x44, 0x3e, 0x79, 0xa4, 0x09, 0x9a, 0x90, 0xff, 0x6e, - 0xc4, 0x12, 0x70, 0xd5, 0x2a, 0x79, 0xf4, 0xcd, 0x0a, 0x66, 0xb7, 0xbb, - 0x7d, 0x92, 0xed, 0x00, 0x75, 0x9a, 0x9d, 0xa4, 0x8a, 0x17, 0x1b, 0xc2, - 0xfd, 0x6d, 0x1d, 0xe3, 0xa9, 0x14, 0x1f, 0x6c, 0x61, 0x4c, 0xa9, 0x7e, - 0x96, 0x96, 0xa4, 0x4a, 0xe3, 0x26, 0xd0, 0xca, 0x1d, 0x09, 0x1a, 0xab, - 0xb0, 0x30, 0xa8, 0x82, 0x46, 0x75, 0x23, 0x9a, 0xea, 0xd6, 0xcd, 0xbf, - 0x6b, 0x9d, 0xe0, 0xc3, 0x71, 0xc9, 0x25, 0xf4, 0xc4, 0x12, 0x24, 0x9d, - 0x31, 0x20, 0x01, 0x03, 0xcf, 0x67, 0xec, 0x76, 0x13, 0x1a, 0xd2, 0xbf, - 0xbe, 0x7b, 0xf3, 0x0a, 0x31, 0xde, 0x81, 0x86, 0x60, 0x0d, 0x11, 0xbd, - 0x35, 0x73, 0x0a, 0x69, 0x96, 0xca, 0xc1, 0x0e, 0xc1, 0x22, 0x4b, 0x71, - 0xc1, 0x2b, 0xcf, 0x1f, 0xf8, 0x5a, 0x2a, 0xc2, 0xf9, 0x39, 0x0a, 0xda, - 0xd7, 0x54, 0xe0, 0xeb, 0xb1, 0xf6, 0x15, 0x3b, 0x8c, 0xf2, 0xfc, 0x06, - 0x64, 0x8a, 0xcf, 0x26, 0x10, 0xdb, 0x11, 0xd0, 0xa1, 0x6e, 0x8d, 0x25, - 0xdc, 0x79, 0x97, 0x9e, 0x9d, 0xe6, 0xb2, 0xdc, 0x23, 0x61, 0x11, 0xf8, - 0x5f, 0x76, 0xe9, 0xdf, 0x24, 0x99, 0xd5, 0x19, 0x3d, 0x3d, 0xaf, 0x13, - 0x10, 0x2d, 0xd9, 0xe4, 0x3e, 0xb5, 0x1a, 0x16, 0x6f, 0xfd, 0x98, 0x23, - 0xff, 0x8d, 0x88, 0xe1, 0xfd, 0xbd, 0xcf, 0xcb, 0xea, 0x17, 0x71, 0xa1, - 0x20, 0x2d, 0x97, 0xf4, 0xb6, 0x6c, 0x1a, 0x8d, 0x91, 0x0c, 0xb6, 0x6f, - 0x5f, 0x40, 0x5f, 0x8c, 0x78, 0x6b, 0x79, 0xe9, 0xdf, 0x8e, 0x1d, 0xf6, - 0x4f, 0x87, 0x1f, 0xbd, 0xd9, 0x5c, 0xa3, 0xf8, 0x65, 0x6b, 0x70, 0x4c, - 0xee, 0x55, 0xf2, 0x2b, 0x29, 0x9d, 0x64, 0x66, 0xef, 0x5a, 0x05, 0x44, - 0xab, 0xe9, 0xfb, 0x9e, 0xf8, 0xe9, 0x45, 0x8a, 0x3f, 0xb7, 0x5f, 0x32, - 0x8c, 0x8a, 0x36, 0xaf, 0xa3, 0x3f, 0x2b, 0xa6, 0xa8, 0x0d, 0xfd, 0x34, - 0xcf, 0x59, 0x2e, 0x3c, 0xa2, 0x17, 0x47, 0x83, 0x45, 0x6a, 0xcd, 0xcf, - 0xb5, 0x58, 0x9c, 0xcd, 0x36, 0x2e, 0x09, 0xb0, 0xe9, 0xd3, 0x10, 0x6b, - 0xc8, 0xfd, 0x91, 0x03, 0xeb, 0x3d, 0xcc, 0xe8, 0x26, 0x9f, 0xfa, 0xab, - 0x78, 0x88, 0x4c, 0x3a, 0x95, 0x57, 0x0f, 0x0b, 0x67, 0xd8, 0x63, 0xc5, - 0x6f, 0x68, 0x95, 0xa7, 0xb6, 0xe0, 0x40, 0x9e, 0x51, 0xc4, 0xd4, 0x20, - 0x47, 0x02, 0x6d, 0xf4, 0x73, 0x06, 0xbf, 0x45, 0x92, 0x83, 0xb4, 0xd6, - 0x3f, 0x4a, 0xe7, 0xa5, 0x54, 0x7c, 0x1c, 0x47, 0x8a, 0xbe, 0xa8, 0x35, - 0x37, 0x8f, 0x0f, 0x5e, 0xfa, 0xb6, 0x65, 0xc8, 0x17, 0x90, 0x08, 0xb7, - 0x1f, 0xc1, 0x6b, 0xa3, 0xd5, 0x0c, 0x6f, 0x17, 0xa2, 0x5e, 0x12, 0x85, - 0x9c, 0xb2, 0xd4, 0x87, 0x6f, 0xe4, 0x95, 0xfe, 0x21, 0xb7, 0x92, 0x03, - 0x42, 0x36, 0xdb, 0x25, 0x40, 0x24, 0xde, 0x98, 0xe4, 0x1f, 0x43, 0x98, - 0x95, 0xdb, 0xb0, 0x8a, 0x7d, 0xa7, 0x86, 0x77, 0xd0, 0xd0, 0x71, 0x54, - 0x94, 0x9d, 0x78, 0xc7, 0x66, 0x9e, 0xa1, 0x69, 0xfa, 0x1a, 0xdd, 0x0d, - 0x9b, 0xc2, 0xd3, 0x79, 0x32, 0x3c, 0x24, 0x39, 0xbf, 0x1f, 0xbb, 0x14, - 0x4b, 0x71, 0x27, 0xfc, 0xed, 0x84, 0x2b, 0x31, 0x67, 0xd9, 0x9d, 0x38, - 0x2a, 0xa8, 0x5c, 0x7b, 0x35, 0x0b, 0x84, 0x80, 0xb2, 0x22, 0x34, 0x91, - 0x79, 0xfe, 0xba, 0x54, 0xbd, 0x5f, 0x73, 0xe5, 0x5a, 0xc7, 0x00, 0x0b, - 0xdf, 0x58, 0x38, 0x40, 0xc0, 0xfd, 0xe5, 0xaf, 0x27, 0xfa, 0x3c, 0xa5, - 0x73, 0xc3, 0xf8, 0xee, 0xca, 0x5b, 0x9e, 0x63, 0x5b, 0x00, 0x8b, 0xec, - 0x30, 0xbf, 0x87, 0xf6, 0x4d, 0x41, 0x73, 0xde, 0xf5, 0x8f, 0x3a, 0x8f, - 0x2c, 0x32, 0xaa, 0xca, 0x6e, 0x2f, 0xb8, 0x75, 0x8f, 0xa6, 0x47, 0xb0, - 0x05, 0xc7, 0xa7, 0x40, 0x53, 0xb0, 0x18, 0xcb, 0xd8, 0x42, 0x9d, 0x01, - 0xfd, 0xdf, 0xdd, 0x25, 0xe3, 0x8f, 0xfe, 0x84, 0xad, 0x6f, 0xf7, 0xff, - 0x09, 0x1b, 0x6c, 0x0b, 0x83, 0x40, 0xd5, 0xca, 0xe3, 0x37, 0xca, 0x68, - 0xe8, 0x99, 0x6a, 0xc0, 0xaf, 0xb1, 0xe1, 0xf6, 0xdf, 0xe0, 0xa3, 0x29, - 0x0b, 0x6c, 0x95, 0xdc, 0xb9, 0x85, 0xd1, 0xb5, 0xb4, 0xce, 0xbe, 0x2c, - 0xa6, 0x60, 0x9d, 0xfe, 0x04, 0x68, 0x66, 0xd7, 0x10, 0xe7, 0xd8, 0x38, - 0x67, 0xbb, 0x67, 0x42, 0x60, 0x9d, 0xc8, 0xb6, 0x07, 0x04, 0x88, 0x23, - 0x0e, 0xab, 0x2c, 0x13, 0xa2, 0x0a, 0xfb, 0x67, 0x2a, 0x4e, 0x66, 0x2f, - 0xee, 0x88, 0xc6, 0x81, 0x07, 0x5c, 0x0d, 0x7e, 0xe6, 0xa7, 0x48, 0xbc, - 0xf3, 0x5f, 0x11, 0x78, 0x5e, 0x41, 0x21, 0xde, 0x68, 0xb2, 0x2c, 0x0a, - 0x54, 0xa3, 0x8f, 0xd5, 0x6e, 0x56, 0xe5, 0x18, 0x58, 0xc2, 0x62, 0x84, - 0x11, 0xd2, 0x20, 0x33, 0x33, 0x30, 0xa4, 0x50, 0x80, 0xfa, 0x68, 0xc4, - 0x07, 0x23, 0x70, 0xb4, 0xbc, 0x40, 0x34, 0x85, 0x03, 0x40, 0xcc, 0xc1, - 0x58, 0x25, 0xb4, 0x5f, 0x23, 0x54, 0x97, 0xa4, 0xf6, 0xf5, 0x14, 0xa6, - 0xd3, 0x94, 0x84, 0x15, 0x7d, 0x06, 0x60, 0x5e, 0x81, 0xb1, 0x23, 0x59, - 0x98, 0x2d, 0xad, 0xc9, 0xb8, 0xbc, 0x6a, 0xa7, 0x62, 0xf0, 0x2e, 0x1e, - 0x7e, 0x21, 0x9d, 0x74, 0x13, 0x90, 0x38, 0x1f, 0xa9, 0x27, 0xcb, 0x35, - 0x37, 0x3c, 0x28, 0x3e, 0xb7, 0x75, 0x34, 0xed, 0x9b, 0xf6, 0x34, 0xea, - 0x35, 0xa1, 0x13, 0xf0, 0x51, 0xfd, 0xd8, 0x52, 0x7b, 0xd4, 0xe0, 0x65, - 0x0b, 0x31, 0x10, 0xed, 0x0a, 0x6e, 0xf0, 0x9f, 0x73, 0x0a, 0xb2, 0xf9, - 0x47, 0xd2, 0x34, 0xe6, 0xbc, 0x07, 0x9d, 0x57, 0x72, 0x80, 0x43, 0x2c, - 0xa5, 0x6b, 0x57, 0xa8, 0x74, 0x43, 0xa5, 0x71, 0x91, 0xb7, 0xb9, 0xd7, - 0x93, 0xad, 0xda, 0x1f, 0x9c, 0x08, 0x2f, 0xa6, 0xca, 0x38, 0xba, 0x98, - 0x47, 0xcb, 0xe7, 0xb5, 0xbc, 0x23, 0x9c, 0x83, 0xb8, 0x06, 0xd6, 0x0f, - 0x2b, 0x74, 0xc9, 0xa5, 0xf3, 0x47, 0x58, 0x3f, 0x2a, 0x93, 0xed, 0xf9, - 0x90, 0xb3, 0x37, 0xe3, 0x59, 0xb8, 0xe2, 0x59, 0x76, 0x38, 0x62, 0xdf, - 0x5c, 0x74, 0xfd, 0x73, 0x3c, 0x29, 0x93, 0xe3, 0x1d, 0x17, 0xda, 0x53, - 0x43, 0xdf, 0x7b, 0x58, 0xf8, 0x59, 0xf1, 0xe7, 0xab, 0x3f, 0x05, 0x6d, - 0x0d, 0xb7, 0xbd, 0xf1, 0x25, 0x95, 0x30, 0xc4, 0xbf, 0x4f, 0xc7, 0x23, - 0x55, 0x4d, 0xe7, 0xdc, 0xb0, 0x1f, 0x34, 0x20, 0xfc, 0x6b, 0xec, 0x4d, - 0x3c, 0x18, 0x78, 0xd4, 0x28, 0xba, 0x5e, 0x93, 0xff, 0x2a, 0xd1, 0x7e, - 0xc7, 0x22, 0x29, 0xb3, 0xf0, 0xb2, 0x47, 0x18, 0xef, 0xaa, 0xbd, 0x27, - 0xd2, 0xca, 0xf6, 0x4e, 0xb5, 0x86, 0x78, 0xa0, 0xe5, 0xb5, 0xf5, 0x1e, - 0x4d, 0x1c, 0x3d, 0x5f, 0x2f, 0x72, 0xb1, 0x5c, 0x13, 0xea, 0x13, 0xf9, - 0x87, 0x20, 0x3e, 0x84, 0x3f, 0x6c, 0x6b, 0x3e, 0xf3, 0xdf, 0xfc, 0x6b, - 0xc3, 0x51, 0x72, 0x4e, 0xe0, 0x23, 0x81, 0x8c, 0x95, 0x07, 0x74, 0x94, - 0x6f, 0x52, 0xff, 0x02, 0x2d, 0x60, 0x5b, 0xd7, 0x5b, 0x12, 0x70, 0xdc, - 0x94, 0x0f, 0x31, 0xf8, 0xc0, 0x73, 0xed, 0x8a, 0x95, 0x0e, 0x7f, 0x97, - 0x3d, 0x2b, 0x47, 0x93, 0xa5, 0xb8, 0xec, 0x4a, 0xd9, 0xae, 0x87, 0x71, - 0xd5, 0xae, 0x87, 0x77, 0x94, 0xb7, 0xc8, 0x22, 0x91, 0xb4, 0x50, 0xe8, - 0x77, 0xd6, 0x6f, 0xcb, 0x99, 0x8b, 0xfd, 0xa8, 0xed, 0xd3, 0x35, 0x08, - 0xd2, 0x95, 0x61, 0x0b, 0x03, 0xff, 0x7b, 0x7f, 0x02, 0x57, 0x6e, 0xa9, - 0x58, 0x3d, 0xa2, 0xf0, 0xb6, 0x17, 0x09, 0x22, 0x31, 0xd4, 0x2d, 0xb7, - 0xd6, 0xad, 0xd1, 0xdf, 0xd6, 0x05, 0xc8, 0x52, 0x93, 0xc4, 0x81, 0x98, - 0xc7, 0x20, 0x7f, 0x60, 0xed, 0xe3, 0xdd, 0x91, 0xbe, 0x38, 0xeb, 0xe2, - 0x86, 0x4f, 0x51, 0xf5, 0x55, 0xdc, 0xbd, 0x7e, 0x8a, 0xaa, 0x11, 0x4e, - 0x1e, 0x73, 0x72, 0x21, 0x3a, 0xeb, 0xa4, 0x67, 0x1c, 0xf9, 0x43, 0x2a, - 0x7e, 0xbe, 0x7c, 0x3a, 0x6c, 0x54, 0xf7, 0xb4, 0xb7, 0xb6, 0x2e, 0xfe, - 0x4f, 0x4b, 0xc0, 0x27, 0x99, 0xba, 0x3b, 0x17, 0x7d, 0x13, 0x82, 0x30, - 0x7d, 0x95, 0xb7, 0x1e, 0x53, 0x27, 0x7a, 0x14, 0x01, 0xef, 0x0c, 0xe2, - 0x99, 0xb0, 0x26, 0x7b, 0x16, 0xd1, 0x2a, 0x21, 0xeb, 0x0e, 0x8b, 0x1b, - 0x1d, 0x45, 0x03, 0x6b, 0x09, 0x50, 0xcd, 0xe6, 0x60, 0xbb, 0x21, 0xd5, - 0xa6, 0xf8, 0x2f, 0xb4, 0x53, 0x78, 0xc8, 0x13, 0x15, 0x38, 0x0e, 0x42, - 0xd3, 0x9a, 0x95, 0xfb, 0x97, 0xbe, 0xb9, 0x77, 0x9d, 0x1d, 0x36, 0xf3, - 0xb4, 0x27, 0x31, 0xdd, 0xf5, 0xb4, 0xa1, 0xa1, 0xae, 0x2a, 0x9b, 0xfd, - 0xd8, 0x4a, 0x57, 0x71, 0xbd, 0xcc, 0x00, 0xb6, 0x15, 0xd1, 0x36, 0x15, - 0x05, 0x2a, 0xea, 0x4a, 0xcc, 0x18, 0x85, 0x58, 0x9c, 0x40, 0x19, 0x72, - 0x38, 0x32, 0x07, 0x84, 0x40, 0xae, 0x9a, 0xee, 0xe4, 0x15, 0xb1, 0xfc, - 0x9f, 0xce, 0xed, 0x45, 0xd4, 0x03, 0xf8, 0x81, 0x62, 0x10, 0x4b, 0x25, - 0x76, 0x95, 0x57, 0x4e, 0xaa, 0x60, 0xec, 0x88, 0x9b, 0x56, 0x51, 0x75, - 0x96, 0x16, 0xfc, 0x22, 0x24, 0xfc, 0xa7, 0x37, 0x6b, 0x13, 0x8a, 0x02, - 0x9f, 0x93, 0x2c, 0x6b, 0x38, 0x96, 0x78, 0xbb, 0x69, 0x76, 0x12, 0x35, - 0x33, 0x65, 0x83, 0x59, 0x84, 0xae, 0x76, 0xc7, 0x4d, 0x13, 0xda, 0xb1, - 0x7b, 0x88, 0x42, 0xb5, 0x07, 0xd4, 0x24, 0x0b, 0xa1, 0x81, 0x69, 0x3c, - 0x9f, 0xc8, 0x03, 0x01, 0x5e, 0xbf, 0xc0, 0x1b, 0xa1, 0x83, 0xbc, 0xfe, - 0x4f, 0x6b, 0x7a, 0x03, 0x33, 0x25, 0x9f, 0xb9, 0x39, 0x21, 0x9c, 0x1d, - 0x2f, 0xc0, 0x89, 0x1a, 0xac, 0x8d, 0x0f, 0x1e, 0x0d, 0x7e, 0x2f, 0x5a, - 0x1e, 0xf2, 0xa3, 0xb3, 0xed, 0x3e, 0x1c, 0xb2, 0x14, 0x5f, 0x16, 0xf1, - 0x14, 0x7f, 0x4e, 0x88, 0x9c, 0xb0, 0xc7, 0xa7, 0x2b, 0x42, 0xfb, 0xb5, - 0xe8, 0x42, 0xc3, 0x5c, 0x73, 0x54, 0x85, 0x67, 0x89, 0xfc, 0x6c, 0x8a, - 0xe4, 0xcd, 0x9b, 0x2d, 0x4e, 0xa4, 0x65, 0x46, 0xd5, 0x9c, 0xfc, 0xe3, - 0xdc, 0x17, 0xeb, 0xed, 0xa8, 0x97, 0xfc, 0x4d, 0x4d, 0x81, 0xb4, 0xcf, - 0xaa, 0xb6, 0x27, 0xe0, 0xe2, 0x17, 0x2b, 0xd4, 0xb6, 0xec, 0x43, 0x26, - 0x8e, 0x07, 0x18, 0xe6, 0x20, 0xfa, 0x26, 0x95, 0x68, 0x90, 0x93, 0x97, - 0xb5, 0xc2, 0xc5, 0xf6, 0xf7, 0xf9, 0xfb, 0x28, 0x44, 0x6d, 0x70, 0x75, - 0x99, 0xb5, 0xc0, 0xc1, 0xd2, 0xd7, 0xdf, 0xfc, 0xfd, 0x01, 0x07, 0x09, - 0x16, 0x3b, 0x4c, 0x4f, 0x55, 0x63, 0x79, 0x7a, 0x88, 0x8b, 0x94, 0x9a, - 0xad, 0xc4, 0xc7, 0xd4, 0xf3, 0x16, 0x36, 0x5b, 0x95, 0xab, 0xdc, 0xe4, - 0xf5, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x34, 0x69, 0x80, 0xe5, 0x19, 0x14, 0x72, 0x2c, 0xb3, 0xdc, 0x40, 0x2d, + 0xca, 0xc9, 0xfa, 0x9a, 0xcb, 0xa9, 0xf1, 0x89, 0xe6, 0xe1, 0x2c, 0xba, + 0x7a, 0x15, 0x18, 0x1b, 0xf9, 0x5f, 0x88, 0x30, 0xe3, 0xb0, 0x27, 0x1b, + 0x4a, 0x9f, 0x84, 0xd4, 0x5a, 0x1a, 0x29, 0xc1, 0x8d, 0x15, 0xea, 0x25, + 0x4e, 0x9f, 0x5e, 0x6d, 0xbd, 0x0f, 0x12, 0xad, 0x8a, 0x70, 0x08, 0xdf, + 0x06, 0x7e, 0x93, 0x14, 0x69, 0xa9, 0xc3, 0x57, 0x59, 0x73, 0x66, 0x77, + 0x45, 0x6a, 0x90, 0x1c, 0xbf, 0xc7, 0x9b, 0xf7, 0x35, 0x1f, 0x55, 0x85, + 0xb7, 0xa2, 0x59, 0x04, 0x90, 0x83, 0x9e, 0x30, 0x13, 0xd3, 0x10, 0x37, + 0xa0, 0x8a, 0x1c, 0xd3, 0x50, 0x1e, 0x4b, 0x65, 0x82, 0x30, 0xf0, 0x31, + 0x84, 0x95, 0xc4, 0x98, 0xd7, 0x04, 0x40, 0xd5, 0x78, 0xc7, 0xf7, 0xbd, + 0x61, 0xc7, 0xa1, 0xa3, 0xda, 0x31, 0x5c, 0x40, 0x30, 0x69, 0x8b, 0xc7, + 0x0e, 0xb3, 0x31, 0xbb, 0xb8, 0x3b, 0xab, 0x5a, 0x6b, 0x63, 0x33, 0x8f, + 0x11, 0x31, 0x55, 0x84, 0x5d, 0x97, 0x38, 0x9d, 0x29, 0x4e, 0x1d, 0x3b, + 0x77, 0x65, 0x8c, 0x1e, 0x24, 0xa4, 0x38, 0xf9, 0xcd, 0xf1, 0x3b, 0x1e, + 0x01, 0x1c, 0x2e, 0x5b, 0x25, 0xdc, 0xc2, 0x18, 0xa9, 0x75, 0x76, 0x5b, + 0xa7, 0x9e, 0x63, 0x19, 0x12, 0xb0, 0xad, 0x10, 0xcc, 0x8b, 0xbd, 0x90, + 0xe7, 0xba, 0x25, 0x8a, 0x70, 0x2a, 0x9b, 0x5e, 0x6d, 0x72, 0xf5, 0x78, + 0xb5, 0xa9, 0x42, 0xb9, 0x91, 0x7a, 0x39, 0x89, 0xae, 0x8a, 0xe0, 0xb9, + 0x8c, 0xde, 0x12, 0x8b, 0x52, 0x95, 0x89, 0xc2, 0xfb, 0xba, 0xa8, 0x2a, + 0x81, 0x7e, 0xf2, 0xb3, 0xd9, 0x16, 0x97, 0x88, 0x38, 0x7c, 0x61, 0x2e, + 0x24, 0x88, 0xb6, 0x2a, 0xb9, 0x66, 0x4d, 0x2e, 0x06, 0xb3, 0xf2, 0x2d, + 0xe1, 0xeb, 0x09, 0x1e, 0x0e, 0x89, 0xaf, 0xe5, 0xb0, 0x90, 0xe1, 0xb8, + 0x1d, 0x68, 0x67, 0xb2, 0xbe, 0xa7, 0xc0, 0x19, 0x07, 0x9b, 0x29, 0x3d, + 0x8b, 0x10, 0x58, 0x22, 0xf0, 0xcb, 0x34, 0xfd, 0xc0, 0x3e, 0x12, 0x10, + 0x06, 0x2e, 0x4e, 0x1e, 0x28, 0x0c, 0xe3, 0xb5, 0x8d, 0x87, 0xf8, 0x43, + 0xde, 0x43, 0x08, 0x24, 0x08, 0x22, 0x03, 0x90, 0x67, 0x6b, 0x07, 0xe6, + 0xae, 0x5c, 0x1b, 0x6f, 0xa7, 0x7d, 0x57, 0x12, 0x49, 0xa3, 0x7e, 0xfd, + 0x41, 0xe9, 0x4d, 0xaf, 0x2d, 0x96, 0xa5, 0x40, 0x42, 0x65, 0x0f, 0x77, + 0xaa, 0xab, 0x3c, 0x43, 0xec, 0x5a, 0xfe, 0xa0, 0x8e, 0x55, 0xbb, 0x49, + 0x49, 0x52, 0xaa, 0x40, 0xb5, 0x09, 0x5e, 0x7c, 0x1b, 0x98, 0xd8, 0x10, + 0x4a, 0xb0, 0x7e, 0x7d, 0xbf, 0xc5, 0xf6, 0xf6, 0x82, 0x67, 0x61, 0xe6, + 0x85, 0xd0, 0x6a, 0x3a, 0x00, 0xf3, 0x88, 0x41, 0xa2, 0xba, 0x8d, 0x2c, + 0xcd, 0xe1, 0x14, 0x5c, 0xd4, 0xb0, 0x64, 0x3d, 0x95, 0x3d, 0x8f, 0xd4, + 0xc4, 0x85, 0x9b, 0xb7, 0x2f, 0x33, 0x8b, 0x9a, 0x1c, 0x03, 0x8f, 0x88, + 0xce, 0xfb, 0x5b, 0x33, 0xf8, 0x90, 0x78, 0xf7, 0xed, 0x8f, 0xa0, 0x50, + 0x53, 0x4b, 0x61, 0x97, 0xcc, 0xd2, 0x44, 0xb3, 0xbb, 0xd7, 0x06, 0x6f, + 0x6c, 0x4b, 0xbe, 0x74, 0x82, 0xec, 0xeb, 0xad, 0x20, 0x3e, 0x80, 0x79, + 0x59, 0x9d, 0x6a, 0xdc, 0xc2, 0x5e, 0xfc, 0x15, 0x1e, 0x3b, 0xe9, 0xc0, + 0xd7, 0x43, 0x5a, 0xc1, 0xcb, 0x3a, 0x57, 0x23, 0x81, 0xda, 0x12, 0x3a, + 0x67, 0x98, 0xcf, 0x21, 0xd1, 0x98, 0x35, 0xf9, 0xb9, 0x99, 0xd0, 0x9c, + 0x0b, 0x0a, 0x09, 0xf8, 0x6a, 0x9c, 0xf8, 0x7f, 0x2e, 0xd5, 0x13, 0x3e, + 0x36, 0xea, 0x6d, 0x69, 0x86, 0x18, 0x27, 0x96, 0x61, 0x2b, 0xd0, 0x61, + 0x91, 0xc9, 0xe4, 0x94, 0x05, 0x09, 0x53, 0x14, 0x1d, 0xa1, 0x74, 0x50, + 0x3c, 0x9c, 0x87, 0x4b, 0xf0, 0x7a, 0x3b, 0x64, 0x99, 0x45, 0x83, 0xc3, + 0xba, 0xb1, 0xaa, 0x90, 0xe0, 0x43, 0x31, 0x20, 0x0f, 0x86, 0xce, 0x5f, + 0x70, 0x5f, 0xe4, 0x67, 0xa4, 0x74, 0x1b, 0x0b, 0xd5, 0x7c, 0x34, 0xb8, + 0xd6, 0x66, 0x26, 0xc4, 0x2d, 0x72, 0xf7, 0x74, 0x39, 0xf5, 0xbc, 0xb4, + 0xed, 0x2e, 0x3f, 0x19, 0x72, 0x70, 0xa9, 0x3e, 0xfe, 0x68, 0xf7, 0xb2, + 0xa3, 0x0d, 0x6e, 0xbd, 0x9f, 0xa2, 0x29, 0x7f, 0x59, 0x77, 0x3e, 0x3d, + 0x8e, 0x81, 0xce, 0xc9, 0xea, 0x9d, 0xef, 0xd1, 0xb4, 0x43, 0x09, 0x75, + 0x9d, 0x0b, 0xfb, 0x0f, 0x43, 0xaa, 0x29, 0x38, 0x8d, 0xb9, 0x88, 0xf2, + 0xbe, 0x64, 0x5f, 0xfb, 0x3d, 0xe9, 0xed, 0xc1, 0x18, 0x1e, 0x93, 0x4f, + 0x14, 0x96, 0xce, 0xec, 0x5e, 0x31, 0x3f, 0xb9, 0xaa, 0xad, 0x37, 0xdd, + 0x6a, 0x8b, 0xe0, 0x9c, 0x7c, 0x7f, 0xd2, 0x63, 0xc2, 0xc9, 0x5c, 0x87, + 0xd5, 0xf8, 0x84, 0xbb, 0x75, 0xea, 0xd6, 0x77, 0xb3, 0xa0, 0xe4, 0xbc, + 0xc8, 0xbe, 0xc4, 0xf9, 0x9e, 0xd3, 0xee, 0x13, 0xfc, 0x89, 0x1b, 0x6c, + 0xc5, 0x86, 0x9a, 0xc8, 0x5d, 0x05, 0x75, 0x3c, 0x4c, 0xba, 0x0b, 0x32, + 0x91, 0x1a, 0xef, 0xab, 0x17, 0x67, 0xa7, 0xd0, 0x7c, 0x06, 0x1a, 0xf8, + 0x05, 0xc1, 0x76, 0x73, 0x34, 0x90, 0xf0, 0xe2, 0x01, 0x0b, 0xeb, 0xb1, + 0x8e, 0xb8, 0xc6, 0x1c, 0xec, 0x39, 0x20, 0xa3, 0x38, 0x66, 0xc2, 0xff, + 0x81, 0x97, 0xb0, 0x61, 0x5d, 0xae, 0x2d, 0x8e, 0x3b, 0x64, 0x12, 0xaf, + 0xd0, 0x68, 0x75, 0xf1, 0x9f, 0x5b, 0xd7, 0x0a, 0xd4, 0x78, 0xb8, 0x9a, + 0x7f, 0x3c, 0x7e, 0x0e, 0xd3, 0x3a, 0x12, 0xf0, 0x95, 0xbb, 0x0c, 0x2f, + 0x06, 0xad, 0x0c, 0x8f, 0x43, 0xba, 0x82, 0x22, 0x4b, 0x68, 0xc6, 0xc9, + 0xce, 0xc9, 0x92, 0x3c, 0x2f, 0x6c, 0xcd, 0x09, 0x95, 0xe5, 0x01, 0x5d, + 0x7f, 0x9e, 0x73, 0x07, 0x42, 0x62, 0xde, 0x21, 0xca, 0x59, 0x69, 0x71, + 0x36, 0xfd, 0x99, 0x92, 0x3d, 0x05, 0x7b, 0xe5, 0x00, 0x8b, 0x3b, 0xb0, + 0x18, 0xa5, 0x59, 0x43, 0x9b, 0xba, 0x5e, 0x33, 0xbb, 0xe2, 0x5b, 0x75, + 0xad, 0x95, 0xfc, 0x9e, 0xd4, 0x7c, 0x2a, 0x93, 0xce, 0x1e, 0x4a, 0xf3, + 0x0f, 0x0f, 0x68, 0x11, 0x51, 0x9d, 0x2a, 0xf2, 0x32, 0xf3, 0xba, 0x00, + 0x10, 0xa7, 0xbf, 0x23, 0x28, 0x4e, 0xbe, 0xd6, 0x7b, 0x1a, 0x66, 0x1f, + 0xcd, 0x3e, 0x4d, 0xad, 0x4f, 0xed, 0x42, 0x33, 0x0a, 0x5f, 0x8c, 0xb1, + 0x67, 0x72, 0x94, 0x3b, 0xd9, 0x3f, 0xb2, 0x5c, 0xe7, 0x7c, 0x06, 0x80, + 0xa4, 0xb7, 0x92, 0x24, 0xac, 0x4a, 0xff, 0x9a, 0xed, 0xf9, 0x5d, 0x04, + 0xf9, 0x2a, 0xe2, 0x91, 0x7f, 0xdd, 0x97, 0x14, 0x44, 0x56, 0xa3, 0x8e, + 0x47, 0x6b, 0xf8, 0x6f, 0xb5, 0x7f, 0x58, 0xae, 0x61, 0x1a, 0xc6, 0xcd, + 0x7b, 0x2a, 0xbd, 0x90, 0x8e, 0x78, 0xd5, 0x31, 0x2a, 0xe7, 0x2d, 0xc9, + 0xf7, 0xcb, 0x99, 0x9f, 0x3c, 0x42, 0xbe, 0xf6, 0x27, 0x1e, 0xdb, 0x57, + 0xf4, 0xc3, 0xd9, 0xac, 0x1e, 0xa2, 0xd9, 0x3c, 0xc0, 0x07, 0x3c, 0x65, + 0x66, 0x6b, 0x0f, 0x5a, 0x71, 0xcd, 0xbf, 0xff, 0x5e, 0x81, 0x80, 0x80, + 0x4b, 0x6e, 0x8c, 0x36, 0x53, 0x32, 0x35, 0x89, 0x93, 0x9f, 0xa7, 0x74, + 0x7a, 0x68, 0xea, 0x9f, 0x37, 0x27, 0x2f, 0x4c, 0xb9, 0xbb, 0xcc, 0x0d, + 0x52, 0x94, 0x31, 0xd8, 0x66, 0xe9, 0x29, 0xaa, 0xd9, 0xcf, 0x39, 0xcc, + 0x8a, 0x39, 0xca, 0x09, 0xba, 0x15, 0x20, 0xd7, 0xa8, 0x85, 0xe7, 0x9c, + 0x76, 0xef, 0xe5, 0xfe, 0xad, 0x4e, 0x37, 0x98, 0x7c, 0xe2, 0x61, 0x0f, + 0x02, 0x5b, 0xee, 0x4b, 0xee, 0xf2, 0x25, 0xe7, 0xd9, 0xc7, 0x85, 0x13, + 0x17, 0xeb, 0x79, 0x91, 0xe4, 0x6d, 0x68, 0xde, 0xd6, 0xde, 0x12, 0xa8, + 0x48, 0x87, 0x0b, 0x73, 0x32, 0x87, 0x32, 0xc0, 0x60, 0xdf, 0xda, 0xb2, + 0x91, 0x39, 0x5b, 0x8c, 0xce, 0x4d, 0xbf, 0xa9, 0xf7, 0xfd, 0x1e, 0x2d, + 0x2c, 0x3d, 0xee, 0xd6, 0xfe, 0x1b, 0xed, 0x9c, 0xc2, 0x5a, 0x36, 0x29, + 0xb4, 0x72, 0xd8, 0xe4, 0x84, 0xf0, 0x7d, 0xf8, 0xf0, 0x90, 0x84, 0x9d, + 0x78, 0xd2, 0x22, 0xe0, 0x68, 0xaf, 0xc9, 0xe9, 0x9d, 0x3c, 0xf6, 0xa6, + 0x15, 0xfd, 0xeb, 0x77, 0x83, 0x95, 0xa4, 0xbb, 0xf0, 0x53, 0x5c, 0x2d, + 0x97, 0x25, 0x7f, 0x01, 0x2a, 0x29, 0xe6, 0xfa, 0x03, 0x90, 0x44, 0x67, + 0x72, 0xca, 0x16, 0x15, 0x85, 0x20, 0x23, 0xd6, 0x15, 0x55, 0x02, 0xa0, + 0x12, 0xb2, 0x82, 0xc4, 0x08, 0xc7, 0x1c, 0x2f, 0x70, 0x33, 0x1b, 0xfe, + 0xc4, 0x6b, 0x09, 0x13, 0x6d, 0x4f, 0xd4, 0x95, 0xb0, 0x51, 0x42, 0x2b, + 0xd1, 0xea, 0x47, 0x87, 0xef, 0x3c, 0x8b, 0x00, 0x68, 0xa0, 0x73, 0x6f, + 0x8d, 0xe8, 0x26, 0x4c, 0x85, 0xb8, 0x47, 0x30, 0x36, 0x6a, 0xca, 0x64, + 0x92, 0x4f, 0x23, 0x1e, 0xb1, 0x69, 0xfc, 0x13, 0x20, 0x5c, 0xb4, 0xf1, + 0xea, 0xe7, 0x18, 0x98, 0x64, 0x2a, 0x5b, 0xfa, 0xf2, 0xc8, 0x1f, 0x7d, + 0x06, 0xaa, 0x7e, 0x5c, 0x98, 0x85, 0x2e, 0x55, 0x3a, 0xfe, 0xaf, 0x38, + 0x35, 0x54, 0xfa, 0x9e, 0xef, 0x32, 0xb2, 0xbf, 0x82, 0x45, 0x1a, 0xe7, + 0xc4, 0x05, 0xf1, 0x25, 0x30, 0xcb, 0x45, 0x23, 0xd4, 0x8e, 0xb4, 0x3d, + 0x72, 0x43, 0x6d, 0x97, 0xcd, 0xd0, 0x1f, 0x72, 0x84, 0xe6, 0xa8, 0xcb, + 0xeb, 0x6d, 0x67, 0xdb, 0x50, 0xb4, 0x3f, 0xa3, 0xe2, 0x72, 0x91, 0x43, + 0x83, 0xac, 0x59, 0x12, 0x03, 0xba, 0x48, 0x9c, 0xa2, 0x28, 0x2e, 0x42, + 0x6b, 0x05, 0xdb, 0xab, 0x35, 0xe7, 0x7c, 0x63, 0x6e, 0x13, 0xce, 0xb2, + 0x72, 0x5c, 0x91, 0x1f, 0xef, 0xc3, 0xd2, 0x80, 0xd1, 0xca, 0xa7, 0x4b, + 0x35, 0x6f, 0x18, 0x3d, 0x70, 0x91, 0xeb, 0x59, 0x05, 0xf2, 0xb6, 0x15, + 0xde, 0x61, 0x91, 0x21, 0x57, 0x85, 0xf6, 0xe2, 0xe1, 0xba, 0x07, 0x00, + 0xb1, 0xf9, 0xed, 0x74, 0x9b, 0xc5, 0x26, 0x5a, 0xc3, 0x18, 0xa4, 0x0c, + 0x99, 0xc6, 0x8c, 0xf9, 0x01, 0xfc, 0x81, 0xf4, 0x85, 0x9a, 0x91, 0xe4, + 0xd2, 0x48, 0xce, 0xca, 0xe1, 0xb8, 0x9a, 0x7b, 0x24, 0x5d, 0x1d, 0xf9, + 0xdb, 0x74, 0x31, 0x29, 0x27, 0x65, 0xd2, 0x3f, 0x4c, 0x65, 0x1b, 0x32, + 0x12, 0xc3, 0xe2, 0xee, 0x15, 0x9b, 0xfc, 0xa1, 0xd7, 0xb5, 0xae, 0xe7, + 0x4e, 0x53, 0x9f, 0x23, 0x36, 0x3c, 0x11, 0xc8, 0x0f, 0x07, 0x9f, 0x3e, + 0x62, 0x7b, 0x5c, 0x6b, 0xf0, 0x97, 0xc8, 0xf9, 0x28, 0x29, 0x9f, 0x28, + 0x32, 0x9e, 0xb9, 0x69, 0xf6, 0x4c, 0x9a, 0xad, 0x10, 0x89, 0xe4, 0xeb, + 0x39, 0x57, 0xa9, 0xe2, 0xa2, 0xa3, 0xdc, 0x6a, 0x1d, 0xdb, 0x84, 0xb6, + 0xc5, 0x15, 0x60, 0xe6, 0xcf, 0x26, 0xdd, 0x98, 0x68, 0xf5, 0xc7, 0xbc, + 0xb1, 0x07, 0x1c, 0xdd, 0x66, 0x54, 0x92, 0xae, 0xad, 0x80, 0xf6, 0x3e, + 0xd2, 0x2a, 0x23, 0x85, 0x7c, 0x23, 0x3b, 0xe5, 0xaf, 0x0d, 0x17, 0x2c, + 0x76, 0x50, 0xba, 0xbc, 0x6e, 0xad, 0x9d, 0x0c, 0x68, 0x3c, 0xa0, 0xb3, + 0x92, 0x4a, 0xc0, 0x6c, 0xde, 0xad, 0x8a, 0x70, 0xd6, 0xfa, 0x99, 0x6b, + 0xae, 0xf9, 0x97, 0x60, 0x23, 0xf0, 0x8b, 0x7b, 0x05, 0xb7, 0x82, 0x46, + 0x10, 0xeb, 0xbf, 0x9b, 0x0e, 0x9e, 0x18, 0xa0, 0x62, 0x46, 0x70, 0x6a, + 0xf5, 0xc0, 0x16, 0x7a, 0xcc, 0xda, 0x3d, 0xb0, 0xfe, 0x47, 0x5b, 0xe6, + 0x77, 0x5f, 0xee, 0xd7, 0x30, 0x96, 0xf4, 0xb4, 0xfa, 0x29, 0x57, 0x20, + 0xa6, 0xac, 0x64, 0xf1, 0x3d, 0x9f, 0x84, 0x57, 0xf2, 0xf3, 0x94, 0xe0, + 0x19, 0xa6, 0x08, 0xa5, 0xc2, 0xf9, 0x18, 0xf7, 0xe5, 0x3f, 0x81, 0xa3, + 0x77, 0x66, 0xfd, 0x3f, 0x0a, 0x9c, 0x83, 0xd0, 0xa9, 0x22, 0x6d, 0xad, + 0x28, 0x37, 0xc7, 0x0f, 0xa8, 0xc2, 0xca, 0x74, 0x89, 0xbc, 0x0e, 0xfe, + 0x37, 0xd5, 0x47, 0x98, 0xb3, 0x86, 0xeb, 0xe5, 0x80, 0x00, 0x7b, 0xcc, + 0xba, 0x84, 0xb1, 0x03, 0xbe, 0x53, 0x1e, 0xff, 0x0f, 0x9d, 0x97, 0x8a, + 0xa0, 0xb3, 0x30, 0x69, 0x53, 0x57, 0x3f, 0xfd, 0x0c, 0x37, 0xc6, 0x3a, + 0x63, 0x7c, 0xd7, 0xd2, 0x42, 0x5b, 0x6f, 0xa3, 0x85, 0x0c, 0xc7, 0xaa, + 0xb3, 0xc6, 0xe8, 0x75, 0x8d, 0x4d, 0xd2, 0x99, 0x39, 0xdb, 0xa4, 0x88, + 0x5f, 0x95, 0x73, 0xe2, 0x1b, 0x38, 0x1e, 0xdc, 0xa5, 0x80, 0xaa, 0xed, + 0x49, 0xae, 0x88, 0x87, 0x93, 0x76, 0xd3, 0x89, 0x86, 0x93, 0x6c, 0xf5, + 0xb3, 0xa3, 0x3d, 0x52, 0xa3, 0x2a, 0x37, 0x26, 0x07, 0x98, 0x4c, 0x55, + 0x0e, 0xd4, 0x34, 0xbb, 0x9b, 0x0d, 0x71, 0xe4, 0x45, 0x6b, 0x30, 0x4f, + 0x35, 0x9b, 0x8d, 0xb1, 0x13, 0xad, 0x14, 0xbc, 0xf5, 0x3e, 0x4e, 0x27, + 0x6d, 0x5f, 0x56, 0x2a, 0x90, 0xf3, 0xea, 0xce, 0xab, 0x03, 0x3b, 0xfe, + 0x38, 0x35, 0x09, 0xa5, 0xc5, 0xe9, 0x60, 0xa4, 0x94, 0x37, 0xb9, 0x7e, + 0xa6, 0x98, 0x9b, 0x06, 0xf6, 0x86, 0xbf, 0x50, 0xc7, 0xe1, 0x37, 0x33, + 0x24, 0xd8, 0x97, 0x47, 0xe0, 0x4b, 0x36, 0xaf, 0xcb, 0xf0, 0xe4, 0x07, + 0xdc, 0x4a, 0x8a, 0x60, 0xce, 0x01, 0xd0, 0x9e, 0xd5, 0x8f, 0x2d, 0x4a, + 0x0b, 0x99, 0xd9, 0x04, 0x8f, 0x2e, 0xfc, 0x75, 0xc1, 0x2f, 0xf5, 0x3b, + 0x7f, 0xe2, 0xf2, 0x65, 0x84, 0xd6, 0x0a, 0xee, 0x52, 0xbc, 0x1f, 0x48, + 0x4d, 0x0f, 0x99, 0xd9, 0xe8, 0x6b, 0x2c, 0x88, 0x2c, 0x5b, 0xe7, 0xc7, + 0x83, 0xf6, 0xb9, 0xc8, 0xd3, 0x5a, 0x71, 0xcf, 0x38, 0xfe, 0x1b, 0x03, + 0x6b, 0x38, 0x1f, 0x5e, 0x72, 0xed, 0x99, 0x28, 0xce, 0x65, 0x6f, 0xd8, + 0x98, 0xc2, 0xbf, 0x4e, 0xcc, 0x35, 0x17, 0x23, 0x52, 0x7d, 0x69, 0x2a, + 0x65, 0xc5, 0x54, 0x5c, 0x21, 0x80, 0xe6, 0x4f, 0x15, 0x20, 0xb9, 0x42, + 0xc6, 0xc3, 0x9c, 0x83, 0xa1, 0x01, 0x2e, 0x5e, 0x06, 0xaf, 0x35, 0xc0, + 0x7c, 0xfd, 0x32, 0x22, 0xa1, 0x4b, 0x6a, 0xc3, 0x3f, 0x3d, 0x7b, 0x5c, + 0x32, 0x80, 0x61, 0x7c, 0x62, 0xd3, 0x81, 0xfd, 0xf9, 0xda, 0x7b, 0xfc, + 0x04, 0xb5, 0x63, 0x2e, 0x2f, 0x02, 0x7d, 0x22, 0x61, 0xa5, 0x57, 0x13, + 0x8a, 0x84, 0xb5, 0x7c, 0x52, 0x74, 0x22, 0xbe, 0x2d, 0xe2, 0x4b, 0xc4, + 0x3b, 0x1c, 0x21, 0x99, 0xa5, 0x7e, 0x00, 0xe8, 0x31, 0xcc, 0x4c, 0xb8, + 0x2d, 0x83, 0x10, 0xf5, 0x3d, 0x2c, 0x7d, 0xfa, 0x6b, 0x29, 0x3a, 0x0e, + 0x2d, 0x81, 0x5e, 0xe3, 0x93, 0x4c, 0x51, 0x22, 0x86, 0x0f, 0xee, 0x42, + 0x31, 0x31, 0xb4, 0xbf, 0x2c, 0xb6, 0x66, 0x92, 0xc1, 0xdd, 0x0d, 0xa9, + 0xa4, 0xcd, 0x6d, 0xf1, 0x1e, 0xcc, 0x17, 0xe6, 0x4a, 0xc6, 0xbc, 0xa5, + 0xb6, 0xc9, 0x45, 0xf2, 0xa9, 0x62, 0xdd, 0x0d, 0x7e, 0x26, 0xc8, 0x95, + 0x08, 0x65, 0x72, 0xe9, 0xcb, 0xf3, 0x7f, 0x40, 0x3d, 0x39, 0xd7, 0xff, + 0xa2, 0xb3, 0x54, 0x85, 0xd5, 0xcf, 0xa6, 0x2a, 0x99, 0xc5, 0x65, 0xaa, + 0x8c, 0x1d, 0xe3, 0x12, 0xe8, 0xd7, 0x95, 0xfa, 0x34, 0x4b, 0xc8, 0x23, + 0x72, 0x33, 0x7f, 0x4e, 0x41, 0xae, 0xa7, 0xb2, 0xe6, 0xe9, 0x89, 0xcd, + 0x38, 0xf2, 0x00, 0x5a, 0xb3, 0x2d, 0x8c, 0x35, 0xaf, 0xbc, 0xae, 0x9e, + 0x0e, 0xd2, 0xd0, 0x3c, 0x1f, 0x9f, 0x0a, 0xf4, 0x29, 0xb0, 0xd8, 0xe8, + 0xd2, 0x99, 0xd7, 0x66, 0xdc, 0x07, 0x00, 0x50, 0x8e, 0x98, 0x6b, 0x3c, + 0x13, 0xa3, 0x8f, 0x8c, 0x03, 0x88, 0x0b, 0x18, 0x33, 0xda, 0xb4, 0xae, + 0x6f, 0xac, 0x36, 0xdb, 0x1b, 0x87, 0x2e, 0x26, 0x68, 0x5b, 0xc6, 0xa0, + 0x57, 0xf3, 0x06, 0xb1, 0x2f, 0xd7, 0x9c, 0x66, 0x19, 0xc2, 0x74, 0x7e, + 0xd7, 0x86, 0xd9, 0xa3, 0xe6, 0x9e, 0xaa, 0xdc, 0x85, 0xb4, 0xdd, 0x4c, + 0xdc, 0x8f, 0x6b, 0x10, 0x7f, 0xb6, 0x6c, 0xa0, 0x34, 0xf0, 0x65, 0x39, + 0xe9, 0xb2, 0x6e, 0x18, 0xff, 0xd5, 0xfc, 0x03, 0xb6, 0x0d, 0x6a, 0xf8, + 0x16, 0x56, 0x4a, 0x0c, 0xf0, 0x5f, 0x66, 0x47, 0x3f, 0x2f, 0xf7, 0x47, + 0xe9, 0x95, 0x3c, 0x22, 0x4b, 0x40, 0xae, 0xff, 0x88, 0xe8, 0x60, 0xd0, + 0x07, 0x7e, 0x85, 0x0b, 0x3a, 0x6e, 0x05, 0x44, 0x29, 0xec, 0x0d, 0x83, + 0xd0, 0x5c, 0xcd, 0x71, 0xd5, 0x24, 0x12, 0x55, 0x38, 0x20, 0x15, 0x6b, + 0xbd, 0x8b, 0x88, 0x8c, 0x30, 0xb3, 0x10, 0xae, 0x26, 0x5b, 0x8b, 0xb1, + 0x4d, 0x33, 0xe9, 0x9e, 0x48, 0x22, 0x58, 0x4e, 0xf8, 0xab, 0xca, 0x95, + 0x29, 0x2b, 0xcc, 0xd6, 0x81, 0xde, 0xf5, 0x2c, 0x68, 0x0b, 0xf5, 0x9c, + 0x94, 0xce, 0x99, 0x0e, 0xbf, 0xea, 0x6d, 0x74, 0x41, 0xdd, 0x3c, 0x13, + 0x1f, 0xd9, 0x0c, 0x13, 0xe5, 0xd1, 0xef, 0x2a, 0xe1, 0xf0, 0x70, 0x76, + 0x66, 0x9e, 0x50, 0xc9, 0xda, 0x58, 0xa1, 0x66, 0x06, 0x36, 0xab, 0xd3, + 0x68, 0xe3, 0x54, 0x52, 0xc5, 0x08, 0xe2, 0x42, 0x55, 0xfb, 0x8d, 0x48, + 0xa9, 0x08, 0x95, 0x9d, 0x66, 0x1c, 0x69, 0xda, 0x2e, 0x71, 0xc8, 0x7a, + 0xb2, 0x50, 0xd6, 0x49, 0xc0, 0x2e, 0x52, 0x60, 0x64, 0x95, 0x13, 0x63, + 0x21, 0x69, 0x2e, 0x5e, 0xd4, 0x8a, 0x3b, 0xa3, 0xf5, 0x34, 0xd0, 0x56, + 0x06, 0xb7, 0x96, 0xbe, 0x2c, 0x2c, 0x97, 0x7d, 0x83, 0x07, 0xde, 0xf5, + 0x46, 0xd5, 0xa4, 0xe0, 0x96, 0x88, 0x65, 0x5c, 0x08, 0x2a, 0x37, 0x8f, + 0x99, 0xa6, 0xaf, 0xc8, 0xde, 0xf4, 0xfe, 0x15, 0x1f, 0x2d, 0x32, 0x33, + 0x3a, 0x68, 0x7b, 0x7f, 0x8f, 0xa3, 0xa6, 0xa7, 0xaa, 0xb7, 0xbc, 0xc2, + 0xef, 0xf4, 0x0a, 0x24, 0x66, 0x70, 0x76, 0x82, 0x9a, 0x9f, 0xa6, 0xbe, + 0xd6, 0xdc, 0xe6, 0xeb, 0xf2, 0x35, 0x4b, 0x50, 0xa0, 0xbf, 0xdf, 0xfa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0b, 0x19, 0x2d, 0x36 + 0x00, 0x00, 0x00, 0x00, 0x0b, 0x1e, 0x2d, 0x34 + }; + + static const uint8_t kMLDSAVerifySignature[MLDSA44_SIGNATURE_BYTES] = { + 0x4b, 0x17, 0x18, 0xc2, 0xe9, 0x41, 0xfd, 0xe2, 0x33, 0x66, 0x89, 0x47, + 0xf9, 0xeb, 0x70, 0xe7, 0x6f, 0x4e, 0x42, 0xc8, 0x75, 0xba, 0x3f, 0xee, + 0x9b, 0xc7, 0xc5, 0xb0, 0xb6, 0x91, 0xfd, 0x39, 0x6c, 0xfa, 0xb0, 0x61, + 0x96, 0x6d, 0x68, 0x4b, 0xcb, 0x56, 0x29, 0xf8, 0x19, 0x5f, 0xbf, 0xbb, + 0x74, 0xe4, 0x32, 0xe5, 0xea, 0x9f, 0x6a, 0xd0, 0xba, 0xf9, 0x95, 0x88, + 0x25, 0x17, 0x82, 0x1e, 0x28, 0xee, 0xc0, 0xff, 0x4c, 0x52, 0x57, 0x27, + 0xdc, 0xb4, 0xde, 0x59, 0x72, 0x01, 0xad, 0xb3, 0x45, 0x75, 0xaa, 0xfe, + 0x96, 0x8b, 0x03, 0x6c, 0x14, 0x21, 0xde, 0x7e, 0x8e, 0x69, 0x35, 0x75, + 0x8b, 0x1a, 0x69, 0xa4, 0x00, 0x58, 0xec, 0xcc, 0x0d, 0x8d, 0xdb, 0x9b, + 0x50, 0x53, 0x8b, 0x70, 0xf6, 0xa5, 0xdc, 0x5e, 0x95, 0x6c, 0x69, 0x31, + 0x2d, 0x72, 0x0b, 0x47, 0x3d, 0x0b, 0x53, 0x75, 0x47, 0xfa, 0x6f, 0xb5, + 0x9c, 0x5d, 0x7a, 0xdf, 0x85, 0xb9, 0x18, 0x16, 0xa5, 0x27, 0x9e, 0x48, + 0x7f, 0xce, 0xe0, 0x0d, 0xcc, 0x53, 0x8d, 0x81, 0x15, 0x73, 0x36, 0x2b, + 0x4a, 0x48, 0xc6, 0x9d, 0x86, 0x29, 0xa4, 0xa3, 0x53, 0x11, 0x65, 0x43, + 0x0f, 0xba, 0x97, 0x16, 0x2e, 0xfb, 0x5d, 0x87, 0x7f, 0x5f, 0x5f, 0xd7, + 0xdb, 0x26, 0x8f, 0xa0, 0x65, 0xcc, 0xb3, 0x67, 0xbb, 0xbf, 0x52, 0xd7, + 0x21, 0x4c, 0x4a, 0x40, 0x02, 0x6f, 0x5d, 0xa8, 0xce, 0x00, 0x42, 0x52, + 0xee, 0x80, 0x27, 0xc3, 0x5c, 0xed, 0x54, 0x51, 0xf2, 0x52, 0xd3, 0x97, + 0xb9, 0x1e, 0xae, 0x84, 0x68, 0x0a, 0xa3, 0x23, 0xb6, 0x71, 0x7a, 0x2e, + 0x1a, 0x8c, 0xa8, 0xbf, 0x5e, 0x92, 0x38, 0x6f, 0x88, 0xf5, 0xaa, 0xc4, + 0x35, 0x21, 0x94, 0x34, 0x66, 0x1c, 0xb9, 0xd2, 0xc4, 0x2c, 0xea, 0xf4, + 0xc3, 0x20, 0x73, 0xc8, 0xb3, 0x72, 0x63, 0x7c, 0x46, 0x92, 0x92, 0x96, + 0xb0, 0x12, 0xd5, 0x5d, 0x73, 0x2d, 0x8d, 0x3a, 0xad, 0xe8, 0x91, 0x70, + 0x85, 0x08, 0x85, 0x9f, 0x6d, 0xc9, 0xa7, 0xa5, 0x59, 0xa4, 0xd7, 0xff, + 0xe4, 0x53, 0xf8, 0x1d, 0x4c, 0x75, 0x68, 0xa1, 0x0b, 0xa2, 0xc8, 0xfc, + 0xcd, 0xbf, 0x1f, 0xf7, 0xec, 0x4b, 0x63, 0xd4, 0x0c, 0x96, 0xa8, 0x51, + 0xf0, 0x23, 0x07, 0x6c, 0x19, 0xde, 0xf5, 0x81, 0xbf, 0xee, 0xe0, 0x88, + 0xc5, 0x63, 0xc9, 0x0e, 0x49, 0xa0, 0xc0, 0xe0, 0xb8, 0x2a, 0x04, 0x21, + 0x4f, 0x98, 0x5c, 0xa7, 0x9f, 0x12, 0xf7, 0x88, 0x7a, 0x17, 0xdb, 0x1f, + 0x71, 0xdb, 0x67, 0xb6, 0x58, 0xd3, 0x92, 0x70, 0x11, 0x02, 0xc9, 0x42, + 0xcb, 0x23, 0x8e, 0x32, 0xa5, 0x62, 0xf4, 0x23, 0x88, 0xaf, 0x02, 0x05, + 0x6f, 0xd8, 0x32, 0xd0, 0x24, 0xb0, 0x14, 0x34, 0x54, 0x25, 0xe1, 0xb5, + 0xb7, 0x25, 0x37, 0x91, 0x59, 0x74, 0xb7, 0x84, 0x41, 0xe3, 0x53, 0x4d, + 0xaa, 0xd8, 0xb5, 0xc3, 0x30, 0xc7, 0xf5, 0x75, 0x68, 0x74, 0x6c, 0xe7, + 0xc4, 0xbe, 0x90, 0x5c, 0x1b, 0xea, 0x3e, 0x80, 0xd6, 0x56, 0x37, 0x20, + 0xcd, 0x97, 0x59, 0xf1, 0x84, 0xeb, 0x1e, 0x4a, 0x03, 0x4f, 0x09, 0x29, + 0x07, 0x60, 0x3f, 0x32, 0x51, 0xec, 0x2e, 0x00, 0x0e, 0xce, 0xec, 0x0f, + 0xae, 0x13, 0x05, 0xf8, 0x61, 0x71, 0x61, 0xb1, 0x41, 0x38, 0x94, 0x57, + 0xda, 0x41, 0x26, 0xe1, 0xc0, 0x20, 0xcc, 0xd6, 0x7f, 0xfa, 0x34, 0x03, + 0x72, 0x8e, 0x0c, 0x68, 0x65, 0xfb, 0x8a, 0xda, 0x9a, 0x4e, 0x74, 0x15, + 0x21, 0x16, 0xa1, 0x50, 0x0e, 0x98, 0xca, 0x0e, 0xcf, 0xb7, 0xb8, 0x1d, + 0xe5, 0x19, 0x11, 0x22, 0x9b, 0x5b, 0xc3, 0x1c, 0x8e, 0x6c, 0xff, 0x95, + 0x22, 0x79, 0x65, 0x75, 0xd1, 0x78, 0x66, 0xe4, 0x89, 0x2b, 0x4b, 0xdb, + 0x82, 0x50, 0x2f, 0x28, 0x27, 0xf5, 0xfa, 0x50, 0xc6, 0x79, 0x73, 0xda, + 0x3a, 0x7e, 0x7f, 0x9a, 0x28, 0x21, 0x24, 0x29, 0x1a, 0xf1, 0x4e, 0x0e, + 0xc9, 0x26, 0x97, 0x62, 0x88, 0x50, 0xec, 0x79, 0x8e, 0x2b, 0x23, 0xf9, + 0x86, 0x1b, 0x04, 0x0e, 0x6e, 0x82, 0x80, 0x41, 0x4e, 0x2c, 0xee, 0x6e, + 0x82, 0xbd, 0xf9, 0x64, 0x89, 0x5d, 0x80, 0x00, 0xa4, 0x01, 0x8d, 0xf7, + 0x39, 0xea, 0x9f, 0xa2, 0x6c, 0xea, 0x9e, 0xf4, 0x9c, 0xe0, 0x47, 0x0c, + 0x90, 0x7e, 0x59, 0xe0, 0x19, 0x33, 0xd6, 0x3a, 0x57, 0xa4, 0xc2, 0x94, + 0x5b, 0xc6, 0x25, 0xc6, 0x1d, 0xbf, 0x45, 0x26, 0xeb, 0xb6, 0x8d, 0x43, + 0x78, 0xb1, 0x98, 0x2a, 0x1c, 0xfa, 0x7f, 0x5e, 0x8c, 0xdb, 0x8e, 0x8a, + 0x46, 0x19, 0x5c, 0x5e, 0xde, 0x8b, 0xc3, 0xf1, 0x49, 0xfd, 0xb6, 0x54, + 0x9d, 0xb1, 0x3f, 0x3f, 0x02, 0x04, 0x59, 0x4d, 0x12, 0x54, 0x70, 0x5f, + 0x32, 0xb8, 0x83, 0xb4, 0xd6, 0xd7, 0x5c, 0x41, 0x05, 0x56, 0x1f, 0x32, + 0xbc, 0xa6, 0x31, 0xa9, 0xe3, 0x18, 0x33, 0xde, 0x26, 0x53, 0x02, 0xf1, + 0xb4, 0xc8, 0x27, 0x8d, 0x28, 0xda, 0xfd, 0xdb, 0xfc, 0xf3, 0x2b, 0xe4, + 0x29, 0xa1, 0x2b, 0x25, 0xba, 0x34, 0x63, 0x3c, 0x2c, 0x2f, 0x55, 0xdf, + 0xa6, 0x74, 0x0c, 0x4e, 0x26, 0xf2, 0x87, 0x04, 0x81, 0x33, 0x61, 0x72, + 0x42, 0x53, 0x52, 0x37, 0xd6, 0x99, 0xf7, 0xb9, 0x95, 0x42, 0xe1, 0x60, + 0x0f, 0xaf, 0x7c, 0x4d, 0x4c, 0xbc, 0x30, 0x90, 0x61, 0xb3, 0x0b, 0x1c, + 0xd8, 0x7d, 0xc4, 0x88, 0x2e, 0xdd, 0xb1, 0x8a, 0x30, 0xe6, 0xb3, 0x3b, + 0x42, 0x23, 0xd1, 0x18, 0x43, 0x2a, 0x79, 0x51, 0x61, 0xdc, 0xb6, 0xf0, + 0xf7, 0x85, 0xf8, 0x56, 0x97, 0xf0, 0xdd, 0xd7, 0x26, 0x6a, 0xcc, 0x53, + 0x59, 0x9a, 0xed, 0xfe, 0x36, 0x03, 0xa5, 0xd9, 0xb3, 0x30, 0xc9, 0x37, + 0xaf, 0x0a, 0x38, 0xa3, 0x26, 0x8c, 0x49, 0x1a, 0xdf, 0x8d, 0xf0, 0x05, + 0x07, 0xfe, 0x4f, 0x44, 0xd9, 0x66, 0x76, 0x86, 0x55, 0xb6, 0x3d, 0x4b, + 0xf6, 0xb7, 0x10, 0x3f, 0x82, 0x10, 0x7a, 0x03, 0xa7, 0xc7, 0xb0, 0xc6, + 0x62, 0x98, 0x51, 0x62, 0xbe, 0x71, 0xac, 0x58, 0x52, 0xfd, 0x8d, 0xac, + 0x56, 0xb1, 0x9c, 0xd4, 0xd2, 0xcc, 0x81, 0x2f, 0xe6, 0x5a, 0xad, 0x01, + 0x0c, 0x5b, 0x10, 0x44, 0x95, 0x6b, 0xb2, 0xc9, 0xb4, 0x45, 0x6b, 0x51, + 0x42, 0xef, 0x8d, 0x55, 0x9f, 0x8d, 0xb2, 0xbe, 0xce, 0x05, 0xf7, 0x99, + 0x68, 0x90, 0x5a, 0x98, 0x68, 0xa0, 0x02, 0x48, 0xb5, 0x64, 0xab, 0x94, + 0xcc, 0xa0, 0x2a, 0x44, 0x41, 0x8a, 0x8a, 0x14, 0xb0, 0x45, 0x47, 0x08, + 0x77, 0x37, 0x25, 0xea, 0x3a, 0xb0, 0xbf, 0x28, 0x77, 0x2e, 0xe7, 0x63, + 0xc1, 0x75, 0xae, 0x5c, 0x70, 0xcd, 0x41, 0x72, 0x96, 0x51, 0x35, 0x33, + 0xbc, 0x3a, 0x3e, 0xd5, 0x69, 0x11, 0x8b, 0x1f, 0xc4, 0x76, 0xf8, 0xc0, + 0x50, 0x87, 0x36, 0x23, 0xce, 0x20, 0x6a, 0xc2, 0x18, 0xf2, 0x04, 0x76, + 0x43, 0xf3, 0xcb, 0xa0, 0xa0, 0x94, 0x90, 0x5c, 0x51, 0x3c, 0xa1, 0x3d, + 0x31, 0x96, 0xfb, 0x1f, 0x13, 0x35, 0x7b, 0x5e, 0x74, 0x08, 0x60, 0x19, + 0x11, 0x1a, 0x9e, 0x75, 0x1e, 0x64, 0x35, 0xb4, 0x5b, 0x81, 0x0a, 0x05, + 0xbb, 0xfe, 0xcf, 0xbc, 0xcf, 0x2a, 0x06, 0xf4, 0x8c, 0xee, 0xc0, 0x10, + 0x03, 0xa5, 0x6f, 0x24, 0xcc, 0xb7, 0xa6, 0x8f, 0x0d, 0x2d, 0x52, 0x0e, + 0x5e, 0xa8, 0xb6, 0x93, 0x8e, 0x00, 0x3e, 0xfb, 0x4e, 0x80, 0xf1, 0xbc, + 0xac, 0xbb, 0xce, 0xd5, 0x81, 0x94, 0xcb, 0xfa, 0xd1, 0x07, 0x53, 0x72, + 0xae, 0x67, 0x70, 0xa9, 0x93, 0x5b, 0xa1, 0xa4, 0x02, 0xde, 0x5b, 0xf2, + 0x9f, 0x4f, 0xc3, 0x76, 0xea, 0xa2, 0xee, 0x41, 0xfe, 0x60, 0x3e, 0xa8, + 0x2b, 0x3b, 0x0a, 0x62, 0xa7, 0x06, 0x36, 0xc8, 0xdb, 0xb4, 0x8f, 0x47, + 0xc5, 0x44, 0x29, 0x5e, 0x4f, 0x0c, 0xdd, 0xd4, 0x16, 0x2e, 0xc4, 0xc9, + 0x0b, 0xd1, 0x2c, 0x78, 0xc7, 0x80, 0x36, 0xb8, 0xdc, 0xcf, 0x57, 0x6d, + 0xac, 0xf7, 0x16, 0x33, 0x46, 0x39, 0x03, 0x09, 0x09, 0x3e, 0xda, 0x78, + 0xee, 0x82, 0x80, 0x24, 0xe5, 0x2a, 0x02, 0xe2, 0x76, 0xe9, 0x51, 0x0c, + 0xa3, 0xbf, 0x9d, 0x09, 0xd3, 0x36, 0xaa, 0xe2, 0xa3, 0x3a, 0xbb, 0x6d, + 0x27, 0x53, 0x4a, 0xb4, 0x08, 0x22, 0x49, 0x7d, 0xf5, 0xbc, 0x16, 0x70, + 0x65, 0x5c, 0x01, 0x01, 0x5e, 0xb5, 0xd2, 0x5c, 0x37, 0xb3, 0x2d, 0x7e, + 0x6f, 0x00, 0x63, 0x57, 0x6e, 0x17, 0x34, 0xf4, 0x74, 0x62, 0x85, 0x4b, + 0xaf, 0x93, 0xb7, 0xd7, 0x9d, 0x6b, 0x3f, 0x18, 0x6e, 0x31, 0x4c, 0x0e, + 0xec, 0xd3, 0x09, 0x35, 0x04, 0x94, 0xeb, 0x9e, 0xc8, 0x1f, 0xec, 0xd1, + 0xc6, 0xef, 0x2e, 0xfa, 0xe9, 0x86, 0xfa, 0xc4, 0xae, 0xae, 0x5f, 0x5f, + 0xee, 0xef, 0x51, 0xd4, 0x32, 0x3a, 0x49, 0x3a, 0x61, 0x44, 0x60, 0x0b, + 0x56, 0x4d, 0xa0, 0x91, 0x7c, 0x56, 0xb3, 0x34, 0x94, 0x37, 0x5b, 0x92, + 0x2c, 0x18, 0xdd, 0x91, 0xfd, 0x77, 0xb5, 0xf9, 0xdc, 0xd7, 0x2a, 0x75, + 0x7b, 0xcd, 0x71, 0xef, 0x04, 0x0a, 0xf2, 0x21, 0xf0, 0xb0, 0x5e, 0x3c, + 0x37, 0xb1, 0xc7, 0xb2, 0x73, 0xb1, 0xab, 0x53, 0x74, 0x6b, 0xe8, 0x4c, + 0x5a, 0x44, 0xf3, 0x93, 0xa7, 0x9c, 0x53, 0x84, 0x15, 0x08, 0x30, 0x05, + 0x49, 0xbb, 0xc6, 0xf8, 0xe7, 0x4a, 0x66, 0x41, 0xf4, 0x51, 0xe5, 0x3a, + 0xd7, 0xb4, 0x19, 0xac, 0xf2, 0x41, 0x2d, 0x6d, 0x43, 0x19, 0xa5, 0x61, + 0x16, 0x02, 0xb0, 0xba, 0xb4, 0xae, 0xfb, 0x42, 0x3a, 0x60, 0x37, 0x4a, + 0xcf, 0x20, 0x02, 0x0c, 0x8e, 0xb4, 0x2f, 0x1f, 0x3c, 0xce, 0xb9, 0x0e, + 0xe6, 0x60, 0xd5, 0xe1, 0xbb, 0x6f, 0xaf, 0xa0, 0xf2, 0x6c, 0x50, 0x3a, + 0x34, 0x84, 0x93, 0x9c, 0xcc, 0x6e, 0xa4, 0xbc, 0x96, 0x93, 0x19, 0x22, + 0x0c, 0x67, 0x10, 0xd0, 0x09, 0xcd, 0x77, 0xab, 0x11, 0xd8, 0x71, 0x8e, + 0xd4, 0x44, 0x59, 0x66, 0xb7, 0x6b, 0xc0, 0xd6, 0xcb, 0x2e, 0xd0, 0x55, + 0x2e, 0xe6, 0x78, 0x0f, 0x6a, 0xd0, 0x58, 0xcc, 0x09, 0xeb, 0xa9, 0xc2, + 0xa1, 0x67, 0xd9, 0xe8, 0x4b, 0x2b, 0xa8, 0xbe, 0x4f, 0xd3, 0x3c, 0x42, + 0x36, 0x77, 0xb6, 0x92, 0xf4, 0x38, 0xf6, 0x98, 0x8c, 0xc2, 0xb1, 0xe6, + 0x36, 0x3b, 0x78, 0x46, 0xfd, 0x00, 0xc4, 0x45, 0x02, 0x86, 0xc5, 0xbe, + 0xab, 0x53, 0x8c, 0xbb, 0x49, 0x6b, 0x4c, 0x51, 0xb8, 0x29, 0x11, 0x96, + 0x9a, 0x14, 0x34, 0x6a, 0x4b, 0x5c, 0xa8, 0x5b, 0x48, 0xc2, 0x5f, 0xc8, + 0x47, 0xc1, 0x10, 0xbb, 0x05, 0x42, 0x12, 0x32, 0xbb, 0xe5, 0x28, 0xf4, + 0x7b, 0xdb, 0x41, 0xbf, 0xc2, 0xb4, 0xe5, 0x26, 0x92, 0x7e, 0xbb, 0xf3, + 0x20, 0xee, 0x73, 0x98, 0xe3, 0x07, 0x29, 0x33, 0x98, 0x2c, 0x79, 0xb2, + 0xea, 0xa0, 0x2e, 0x28, 0xb4, 0xa7, 0x98, 0x17, 0xe2, 0x15, 0xff, 0x39, + 0x4b, 0xdc, 0x1d, 0x7b, 0x05, 0xd1, 0x15, 0xad, 0xc8, 0x63, 0x16, 0x11, + 0x65, 0x94, 0x6a, 0x85, 0x6f, 0x02, 0xff, 0xd5, 0x25, 0x7f, 0x02, 0xfc, + 0x4d, 0x00, 0x9b, 0x2e, 0x7e, 0x87, 0x63, 0x35, 0x92, 0xa2, 0xb4, 0xe1, + 0x08, 0xf3, 0xd8, 0x37, 0x86, 0x60, 0x3f, 0x43, 0x4b, 0x6a, 0x52, 0xb5, + 0x49, 0xb3, 0xfb, 0x4c, 0x61, 0x29, 0x78, 0x95, 0x54, 0xab, 0x4f, 0x41, + 0xa0, 0xe9, 0x0f, 0x59, 0x4f, 0x75, 0x51, 0xa1, 0xf8, 0xce, 0xc9, 0x82, + 0xdb, 0x83, 0xe3, 0xc5, 0x9d, 0x98, 0x22, 0x66, 0x64, 0x7b, 0xdf, 0x26, + 0x69, 0xa0, 0x84, 0x2a, 0x2b, 0x92, 0x47, 0xaa, 0x1f, 0xa4, 0x9b, 0x98, + 0x2a, 0x32, 0x76, 0x06, 0x8f, 0xd1, 0x62, 0x0a, 0x7c, 0x53, 0x53, 0x65, + 0x10, 0x16, 0xc5, 0x49, 0x42, 0x02, 0x55, 0xab, 0x33, 0xd1, 0x66, 0x69, + 0x15, 0x39, 0x91, 0xb3, 0x70, 0xde, 0x0b, 0xa1, 0x64, 0xd7, 0xed, 0x16, + 0x42, 0xee, 0x07, 0x3b, 0x19, 0xbd, 0xa5, 0x6a, 0x35, 0x2a, 0xe9, 0x5b, + 0x64, 0x33, 0x53, 0x58, 0x31, 0x06, 0x7d, 0x5f, 0xe6, 0x05, 0x88, 0x56, + 0x77, 0xf0, 0x16, 0xce, 0x20, 0xc0, 0x94, 0x44, 0x22, 0xae, 0x69, 0x42, + 0x30, 0xc6, 0xf2, 0xa9, 0x40, 0x81, 0x2c, 0xeb, 0x8c, 0x44, 0xcb, 0x0c, + 0x45, 0x0f, 0x23, 0xb2, 0x3f, 0x96, 0x15, 0x5d, 0x6d, 0x56, 0xde, 0x58, + 0xef, 0x86, 0x90, 0x58, 0x80, 0x5b, 0xd2, 0xd9, 0x8c, 0x07, 0xae, 0x9e, + 0x57, 0xcb, 0x0d, 0xc3, 0xe2, 0x99, 0xe3, 0x5f, 0x9c, 0x38, 0xca, 0xda, + 0x55, 0x73, 0xaf, 0xf6, 0xfd, 0x28, 0xbb, 0x20, 0x50, 0xbf, 0x98, 0x77, + 0x07, 0x48, 0xad, 0x92, 0x5f, 0xe2, 0xaa, 0x62, 0x3f, 0x24, 0xd3, 0xfe, + 0xc7, 0xb0, 0x91, 0x4b, 0x24, 0x02, 0x6f, 0x03, 0x3b, 0x8b, 0x13, 0xde, + 0x44, 0x93, 0xbb, 0xbe, 0x02, 0xac, 0xd8, 0x56, 0x83, 0xa5, 0xfc, 0x9b, + 0x33, 0x27, 0x28, 0xbd, 0xea, 0x5e, 0xa3, 0x17, 0x19, 0xd7, 0x51, 0x68, + 0x19, 0x8d, 0xd3, 0x2b, 0xb6, 0x75, 0x8f, 0xb3, 0xfd, 0x08, 0x16, 0x69, + 0xe5, 0x23, 0x43, 0x66, 0xa3, 0xc7, 0x3e, 0xf9, 0xe4, 0xa8, 0xe1, 0x1c, + 0x00, 0x4e, 0x06, 0xa2, 0xb0, 0xbe, 0xa6, 0xd6, 0x24, 0x4c, 0x2b, 0xd2, + 0xfd, 0x22, 0xdf, 0x49, 0x55, 0xc6, 0x6a, 0x6c, 0x5f, 0x7a, 0xe8, 0x2a, + 0xd7, 0xe4, 0x5d, 0x44, 0xc6, 0x7e, 0x85, 0x84, 0x32, 0xd1, 0x37, 0xff, + 0xe8, 0xcc, 0xab, 0x05, 0x99, 0xed, 0x43, 0x7c, 0xa9, 0x56, 0x60, 0x8d, + 0xb4, 0x53, 0xc3, 0x45, 0x56, 0x06, 0xea, 0x2d, 0x38, 0xbc, 0x4c, 0x16, + 0x7b, 0xd2, 0xfb, 0x0d, 0xae, 0xac, 0x1f, 0x32, 0x7a, 0x6b, 0x05, 0x87, + 0x0c, 0x6f, 0x8f, 0x1c, 0x1a, 0x26, 0x2f, 0xf1, 0xc7, 0x70, 0x48, 0x44, + 0x71, 0xc7, 0xe8, 0x8f, 0x96, 0x5b, 0x1d, 0x7f, 0xcf, 0xf5, 0x90, 0xb5, + 0x30, 0xb5, 0xd5, 0x33, 0x18, 0x56, 0xb6, 0x45, 0x17, 0x56, 0xb8, 0x3c, + 0xf8, 0x4e, 0xf5, 0xca, 0x11, 0x70, 0x39, 0x8c, 0xf7, 0x46, 0xbb, 0x37, + 0xb6, 0xb5, 0xd5, 0x05, 0x25, 0xb4, 0xe1, 0x5a, 0x75, 0x13, 0x36, 0x41, + 0x9e, 0x4a, 0x78, 0x16, 0x53, 0xf0, 0x2a, 0x77, 0x4e, 0x03, 0x1d, 0x10, + 0x41, 0x10, 0x97, 0x5f, 0xcf, 0x42, 0x25, 0xea, 0xff, 0xb6, 0x1d, 0x97, + 0x99, 0x53, 0xc3, 0x60, 0x17, 0x67, 0xf2, 0x20, 0x50, 0xb5, 0x2a, 0x5a, + 0xfc, 0xa8, 0x5d, 0xae, 0x98, 0x82, 0xaf, 0x3d, 0x74, 0x05, 0xce, 0x50, + 0x30, 0x51, 0xf5, 0xaf, 0x0b, 0x39, 0x00, 0x0b, 0xa9, 0xda, 0xf4, 0xd2, + 0x30, 0xad, 0xb6, 0x19, 0x6b, 0x29, 0xcf, 0x7a, 0x35, 0x55, 0xf4, 0x43, + 0x70, 0x8b, 0x57, 0x37, 0xf2, 0x2e, 0xcf, 0x4a, 0xe2, 0xb7, 0xb2, 0x73, + 0x71, 0x83, 0xe3, 0x2e, 0x60, 0x7e, 0x0b, 0x11, 0xe5, 0x4b, 0xb2, 0x65, + 0xbd, 0x85, 0x2d, 0x91, 0x80, 0x12, 0xa5, 0xf4, 0x2c, 0xe8, 0x27, 0xbb, + 0x60, 0x9b, 0x8c, 0x02, 0x62, 0xf5, 0x51, 0x61, 0x1f, 0xf0, 0x0a, 0x8e, + 0x3a, 0x0c, 0x0a, 0x0a, 0x58, 0x42, 0x2a, 0x5f, 0xfa, 0x3f, 0xed, 0xb5, + 0x62, 0x8a, 0xfb, 0xd0, 0xb7, 0x1c, 0x50, 0xab, 0xad, 0xa5, 0x0a, 0x1d, + 0x7c, 0x79, 0x90, 0x38, 0xb5, 0x02, 0x4d, 0x2a, 0xeb, 0xf3, 0xe3, 0x96, + 0x92, 0x21, 0x26, 0xc6, 0x3a, 0xbe, 0xfa, 0x01, 0x2a, 0xc9, 0x7b, 0x4b, + 0x40, 0xec, 0xfe, 0x9a, 0x4f, 0xf4, 0xbf, 0xb0, 0x83, 0xe9, 0x9e, 0x89, + 0xc4, 0xba, 0x20, 0x1b, 0x9e, 0x3d, 0x75, 0x51, 0xe2, 0x24, 0xc7, 0x1c, + 0x87, 0x1e, 0x94, 0x90, 0xd9, 0xe8, 0xb9, 0x4d, 0x7a, 0x58, 0xd0, 0xdd, + 0xe8, 0x98, 0x1c, 0x0b, 0xde, 0xf4, 0x42, 0xa3, 0x46, 0x15, 0xe4, 0xb4, + 0xd8, 0x8f, 0xcf, 0x0c, 0x5d, 0x16, 0xcb, 0xc1, 0x99, 0x15, 0x35, 0x93, + 0xd0, 0xae, 0x43, 0x06, 0x69, 0x34, 0xd2, 0x33, 0xdf, 0x9d, 0x38, 0x13, + 0xb9, 0x89, 0x8d, 0xa4, 0xbd, 0x11, 0xe9, 0x39, 0x1f, 0x94, 0x06, 0x4e, + 0x95, 0x2a, 0x92, 0xcb, 0x35, 0x06, 0x4b, 0x79, 0x40, 0xf5, 0x17, 0x72, + 0xe3, 0xc2, 0xf0, 0xe7, 0x3e, 0x0d, 0x07, 0x41, 0x21, 0x4f, 0x35, 0x2a, + 0x28, 0x9d, 0x57, 0x8e, 0xe8, 0xe6, 0x5b, 0x20, 0x4b, 0x65, 0xe0, 0xc4, + 0x50, 0x49, 0x60, 0x3e, 0x39, 0xa9, 0x20, 0x8d, 0x2c, 0x16, 0x66, 0x02, + 0xbc, 0xac, 0x47, 0xf8, 0x04, 0xfb, 0xdb, 0x3f, 0xa9, 0xc2, 0xcb, 0x48, + 0x6c, 0x0a, 0xc6, 0x2f, 0x17, 0xf9, 0x8a, 0x25, 0x76, 0x42, 0xd7, 0x7e, + 0x18, 0x8e, 0x62, 0xad, 0xd4, 0xdb, 0xaf, 0x3b, 0xfe, 0xee, 0x34, 0x18, + 0xb4, 0xc5, 0x3d, 0x1b, 0x64, 0xaa, 0xde, 0x44, 0x44, 0x66, 0xa3, 0x0e, + 0xf9, 0xf1, 0x7d, 0xe7, 0x65, 0x47, 0xa3, 0xb9, 0x75, 0x2d, 0x93, 0xde, + 0xbb, 0x67, 0xda, 0x22, 0x36, 0xd7, 0x52, 0x6a, 0xbb, 0x7f, 0x33, 0x27, + 0xdc, 0x2c, 0xc3, 0x15, 0x99, 0x38, 0x5e, 0x86, 0xfb, 0x8d, 0x20, 0x6c, + 0x26, 0xc9, 0x61, 0x9f, 0x4b, 0x76, 0x2c, 0x12, 0x7b, 0x0e, 0xfa, 0xc7, + 0x91, 0x5e, 0xdb, 0xd4, 0x3c, 0x32, 0xca, 0xf7, 0x4f, 0x75, 0xda, 0x87, + 0xb8, 0xb5, 0x7c, 0xa4, 0x63, 0x65, 0xbd, 0x0c, 0x58, 0xbd, 0xa3, 0xa5, + 0x89, 0xa6, 0x5d, 0xf1, 0x6b, 0xae, 0x0e, 0xd1, 0x01, 0x09, 0x2a, 0x31, + 0x50, 0x5d, 0x7b, 0x83, 0x87, 0x97, 0x9b, 0xa6, 0xb7, 0xbf, 0xc3, 0xcf, + 0xda, 0xe1, 0xe3, 0x0e, 0x15, 0x17, 0x18, 0x1b, 0x1c, 0x29, 0x42, 0x5b, + 0x70, 0x79, 0xba, 0xbb, 0xc0, 0xc1, 0xc8, 0xed, 0x0f, 0x13, 0x15, 0x17, + 0x1d, 0x1f, 0x2f, 0x4e, 0x50, 0x51, 0x5e, 0x75, 0x7d, 0x88, 0xb0, 0xb6, + 0xbc, 0xc2, 0xcc, 0xe2, 0xf0, 0x05, 0x2e, 0x46, 0x6a, 0x9b, 0xa4, 0xc9, + 0xca, 0xfd, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x13, 0x24, 0x39, 0x43 }; // Keygen @@ -2081,13 +2292,14 @@ static int boringssl_self_test_ml_dsa(void) { if (!ml_dsa_44_sign_internal_no_self_test(private_key, signature, &sig_len, kMLDSASignPlaintext, mlen_int, NULL, 0, kMLDSASigGenSeed) || - !check_test(kMLDSASignSignature, signature, sizeof(signature), "ML-DSA SigGen signature")) { + !check_test(kMLDSASignSignature, signature, sizeof(signature), "ML-DSA-sign")) { goto err; } // Verify - if (!ml_dsa_44_verify_internal_no_self_test(public_key, kMLDSASignSignature, sig_len, kMLDSASignPlaintext, + if (!ml_dsa_44_verify_internal_no_self_test(public_key, kMLDSAVerifySignature, sig_len, kMLDSAVerifyPlaintext, mlen_int, NULL, 0)) { + AWS_LC_FIPS_failure("ML-DSA-verify failed"); goto err; } diff --git a/util/fipstools/break-kat.go b/util/fipstools/break-kat.go index e4c1a4642f..07f644d303 100644 --- a/util/fipstools/break-kat.go +++ b/util/fipstools/break-kat.go @@ -44,6 +44,8 @@ var ( "ML-KEM-keyGen-encaps": "a7cc68f8d02110ca5720223b9e2a8987c8a24835a20dabcbefa430e74a85af80b9b74b74574c5e5f585459ca3610940f0b57b33344ceacccc135557b82f4968688a0168c1aa2940e5604482bf8b900a4343096446330cfee10917c0338181b7fe8d30f4816087d6299f225417f533ee40473894847bd45291367be6b1a7dee55bb21d60e3828552f4c8a6f3c54fc74cf67a614eeab002a076851879cef2218fdb3766123c2de32a269b6aa4661b69370314c004446f7258c40b2ea789f40ca023bbb1217c2c44b380c6e3194edd129d039218d9b75194a386d944acce7a9720ab026362004e95bf9229290b53613416082e82ba8a42a5ff14759f57712395706b307f7635ecee42317a48eb3b90683f3ab53d17c50f53c6cfb1c0cf59d6f2a981021428a7ac5edf13b26844d83c31d3608710e623aabb24b6c5b48baebc1b3078972589201b7a30bc09315612b067655bec403a69c89eb137c31157971098cb693ba4ae9ae40a8031cec92580bcc1b5ab3ecd1aa5f79aa2cd69249d138c8965a81c87a07eb59a4612e60658f4df028cef8af1b837e0ab0bfedb726904290d0bc41df6a67f7a4166609952439631960648e229a21f2a4d82abad3ec8135dc9bb43c703d3b33e437c9ef7bca91c3465676740125a15ad1707088b101b4273d3c4bf30181b4b2575de75ccfc13312a2a6bcebc477a9668e751629b569bfa20beca09800992c63f04b6b4a7df977a00131c2f8722e5138775235b517a709852167c1d415fdc7ad32f2aaca437e9cc6b248d9ca7c65b405e68d24e81b8688caa22b3cf5c9b147f0cc27e667a80b83ccbb4f4161a5ffd0194b1b5720e68ea0f59997f26740972d2c8124d7a6ad8327c2075a3f76b968d2aaad19c00697599e0be49fa6d65b4088b0be692dcda028095852a0d7205e4417409c0317780305a878fb582963b6953f6b8f0880b050178301d659be3a4db7e0bf2587129164178f32707d40392d85713dea82913999aa6c35aa94b3547abe40e2b0ba82b5b78319182a5a47d173176ba6fa3a4d70a8130b310743fa8aaae314381c9b7f49991f19a4ff8369638de380b5d828b7b5fcfdd91fe68efe16d4cd9eed66d65c1d2d8caf5af4a692", "ML-KEM-encapsulate-ciphertext": "431a4f1b2d2c6c00f1690bbe482541ef3d563774daff83207f96de7e5e4a59d5d936d9443ad422e645793e7a60a9b0a76cd672d20c69b82a5563df52d96f9a6cdfc56fbd4fd8d5a8afeb2a09d92ec854094794b4ed2db381f04c68439608aa9902a4d1689e2eb1e5f07a4a1c709262d7c2ff2f81f6eeaab2a86a41ba210eb1bf8e75febccd1a15b4d7a7b60257c89d00bd81d39fcb8d1ce3278102595dd652f7fb7d5584874f3327b174043b350ebd4d41fe08bd0e854d41cbb027c481da64dc6151b88dececcf022ddac2e22736c147e0773294231c0589967154c526b0b7cdd59568eeff5749a40cb100c60c6480897655d96e9f64d61684c0b3150646732c19409fe565540a31894703cf0179cae85bc8c1a5732649836e48e676405b9591b65ba25f9b489b9e5772aa1ed5a00143cb9f5449fd013457a3c13874cb58c75b52c9b6a9ae495ccb504a89cb5f145695b921632fb85b0316b30d4ad17fef0862d6b1e6ca6a611c8a6a7234b4362c5ca0ad9f7697687798cf624dc9f35fbb376e09953156532a9033709df755b46cc6d83de3a111e19a76b361e0ef14c91db8d91c6c6d9e3e46f42291fd6cbf5cfd122716fb0675698e602ab39ee98e0d8145eebaaa9374f5b3bb0df4d0fd83a40e0d25038c39e9bee01cf79c86f3086158d031d5c5e86bc7e7eb16e622505f2888213884c0b5252289b11fce5bfeebfbef0a32ceaf9c14c6250090028463db6f8d19684f541108fe934d88e7ef5cce9daebb32700b9397691a684298c9bf1b7c22d1bcec3fcacfbb17f2ed2b98b85e6a8fe2482996b5e099e9d0211cb9412614de87dc18d23613ed7f6c29cc37b727116dd901c2817938c29fcd026089336addc09eca90de9a25a6374fee86bcdd06ae3daaf0b1bc5b3b2790d4d9f759bef8ac743612a2bbf6e45de8b22efa61226625d4c39f346b844c5ebec5355866c00b726cc1640cb237c34a20a7c603d251f46e6b3b0fa71b3276835e3e9da5b9485e789614af49f1e9504db2528631fbe1cd7dbee85164e4c099a27a4583e9247d078f8830b46874c1b010bf3cd90eb0774961f239ba", "ML-KEM-encapsulate-shared-secret": "a772df2de250ac7d896bbb820b57f2ae05f9a412ab55baa421d4af6dac62662a", + "ML-DSA-sign": "4a414b45204d415353494d4f20415753323032352e0102030405060708090a0b", + "ML-DSA-verify": "4b1718c2e941fde233668947f9eb70e76f4e42c875ba3fee9bc7c5b0b691fd396cfab061966d684bcb5629f8195fbfbb74e432e5ea9f6ad0baf995882517821e28eec0ff4c525727dcb4de597201adb34575aafe968b036c1421de7e8e6935758b1a69a40058eccc0d8ddb9b50538b70f6a5dc5e956c69312d720b473d0b537547fa6fb59c5d7adf85b91816a5279e487fcee00dcc538d811573362b4a48c69d8629a4a3531165430fba97162efb5d877f5f5fd7db268fa065ccb367bbbf52d7214c4a40026f5da8ce004252ee8027c35ced5451f252d397b91eae84680aa323b6717a2e1a8ca8bf5e92386f88f5aac435219434661cb9d2c42ceaf4c32073c8b372637c46929296b012d55d732d8d3aade891708508859f6dc9a7a559a4d7ffe453f81d4c7568a10ba2c8fccdbf1ff7ec4b63d40c96a851f023076c19def581bfeee088c563c90e49a0c0e0b82a04214f985ca79f12f7887a17db1f71db67b658d392701102c942cb238e32a562f42388af02056fd832d024b014345425e1b5b72537915974b78441e3534daad8b5c330c7f57568746ce7c4be905c1bea3e80d6563720cd9759f184eb1e4a034f092907603f3251ec2e000eceec0fae1305f8617161b141389457da4126e1c020ccd67ffa3403728e0c6865fb8ada9a4e74152116a1500e98ca0ecfb7b81de51911229b5bc31c8e6cff9522796575d17866e4892b4bdb82502f2827f5fa50c67973da3a7e7f9a282124291af14e0ec92697628850ec798e2b23f9861b040e6e8280414e2cee6e82bdf964895d8000a4018df739ea9fa26cea9ef49ce0470c907e59e01933d63a57a4c2945bc625c61dbf4526ebb68d4378b1982a1cfa7f5e8cdb8e8a46195c5ede8bc3f149fdb6549db13f3f0204594d1254705f32b883b4d6d75c4105561f32bca631a9e31833de265302f1b4c8278d28dafddbfcf32be429a12b25ba34633c2c2f55dfa6740c4e26f287048133617242535237d699f7b99542e1600faf7c4d4cbc309061b30b1cd87dc4882eddb18a30e6b33b4223d118432a795161dcb6f0f785f85697f0ddd7266acc53599aedfe3603a5d9b330c937af0a38a3268c491adf8df00507fe4f44d966768655b63d4bf6b7103f82107a03a7c7b0c662985162be71ac5852fd8dac56b19cd4d2cc812fe65aad010c5b1044956bb2c9b4456b5142ef8d559f8db2bece05f79968905a9868a00248b564ab94cca02a44418a8a14b0454708773725ea3ab0bf28772ee763c175ae5c70cd417296513533bc3a3ed569118b1fc476f8c050873623ce206ac218f2047643f3cba0a094905c513ca13d3196fb1f13357b5e74086019111a9e751e6435b45b810a05bbfecfbccf2a06f48ceec01003a56f24ccb7a68f0d2d520e5ea8b6938e003efb4e80f1bcacbbced58194cbfad1075372ae6770a9935ba1a402de5bf29f4fc376eaa2ee41fe603ea82b3b0a62a70636c8dbb48f47c544295e4f0cddd4162ec4c90bd12c78c78036b8dccf576dacf7163346390309093eda78ee828024e52a02e276e9510ca3bf9d09d336aae2a33abb6d27534ab40822497df5bc1670655c01015eb5d25c37b32d7e6f0063576e1734f47462854baf93b7d79d6b3f186e314c0eecd309350494eb9ec81fecd1c6ef2efae986fac4aeae5f5feeef51d4323a493a6144600b564da0917c56b33494375b922c18dd91fd77b5f9dcd72a757bcd71ef040af221f0b05e3c37b1c7b273b1ab53746be84c5a44f393a79c53841508300549bbc6f8e74a6641f451e53ad7b419acf2412d6d4319a5611602b0bab4aefb423a60374acf20020c8eb42f1f3cceb90ee660d5e1bb6fafa0f26c503a3484939ccc6ea4bc969319220c6710d009cd77ab11d8718ed4445966b76bc0d6cb2ed0552ee6780f6ad058cc09eba9c2a167d9e84b2ba8be4fd33c423677b692f438f6988cc2b1e6363b7846fd00c4450286c5beab538cbb496b4c51b82911969a14346a4b5ca85b48c25fc847c110bb05421232bbe528f47bdb41bfc2b4e526927ebbf320ee7398e3072933982c79b2eaa02e28b4a79817e215ff394bdc1d7b05d115adc863161165946a856f02ffd5257f02fc4d009b2e7e87633592a2b4e108f3d83786603f434b6a52b549b3fb4c6129789554ab4f41a0e90f594f7551a1f8cec982db83e3c59d982266647bdf2669a0842a2b9247aa1fa49b982a3276068fd1620a7c5353651016c549420255ab33d16669153991b370de0ba164d7ed1642ee073b19bda56a352ae95b6433535831067d5fe605885677f016ce20c0944422ae694230c6f2a940812ceb8c44cb0c450f23b23f96155d6d56de58ef869058805bd2d98c07ae9e57cb0dc3e299e35f9c38cada5573aff6fd28bb2050bf98770748ad925fe2aa623f24d3fec7b0914b24026f033b8b13de4493bbbe02acd85683a5fc9b332728bdea5ea31719d75168198dd32bb6758fb3fd081669e5234366a3c73ef9e4a8e11c004e06a2b0bea6d6244c2bd2fd22df4955c66a6c5f7ae82ad7e45d44c67e858432d137ffe8ccab0599ed437ca956608db453c3455606ea2d38bc4c167bd2fb0daeac1f327a6b05870c6f8f1c1a262ff1c770484471c7e88f965b1d7fcff590b530b5d5331856b6451756b83cf84ef5ca1170398cf746bb37b6b5d50525b4e15a751336419e4a781653f02a774e031d104110975fcf4225eaffb61d979953c3601767f22050b52a5afca85dae9882af3d7405ce503051f5af0b39000ba9daf4d230adb6196b29cf7a3555f443708b5737f22ecf4ae2b7b2737183e32e607e0b11e54bb265bd852d918012a5f42ce827bb609b8c0262f551611ff00a8e3a0c0a0a58422a5ffa3fedb5628afbd0b71c50abada50a1d7c799038b5024d2aebf3e396922126c63abefa012ac97b4b40ecfe9a4ff4bfb083e99e89c4ba201b9e3d7551e224c71c871e9490d9e8b94d7a58d0dde8981c0bdef442a34615e4b4d88fcf0c5d16cbc199153593d0ae43066934d233df9d3813b9898da4bd11e9391f94064e952a92cb35064b7940f51772e3c2f0e73e0d0741214f352a289d578ee8e65b204b65e0c45049603e39a9208d2c166602bcac47f804fbdb3fa9c2cb486c0ac62f17f98a257642d77e188e62add4dbaf3bfeee3418b4c53d1b64aade444466a30ef9f17de76547a3b9752d93debb67da2236d7526abb7f3327dc2cc31599385e86fb8d206c26c9619f4b762c127b0efac7915edbd43c32caf74f75da87b8b57ca46365bd0c58bda3a589a65df16bae0ed101092a31505d7b8387979ba6b7bfc3cfdae1e30e1517181b1c29425b7079babbc0c1c8ed0f1315171d1f2f4e50515e757d88b0b6bcc2cce2f0052e466a9ba4c9cafdfe0000000000000000000000000013243943", } listTests = flag.Bool("list-tests", false, "List known test values and exit") From 51c6c84cc62c9ce0853b6dba365aa07c2bfc40a3 Mon Sep 17 00:00:00 2001 From: Andrew Hopkins Date: Fri, 7 Mar 2025 15:35:28 -0800 Subject: [PATCH 9/9] Add CMAC benchmark for AWS-LC (#2218) ### Description of changes: Adds a benchmark for CMAC, OpenSSL 1.0.2 does not support CMAC. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license. --- tool/ossl_bm.h | 1 + tool/speed.cc | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/tool/ossl_bm.h b/tool/ossl_bm.h index e5b874809c..beb7080506 100644 --- a/tool/ossl_bm.h +++ b/tool/ossl_bm.h @@ -64,6 +64,7 @@ OSSL_MAKE_DELETER(BN_CTX, BN_CTX_free) OSSL_MAKE_DELETER(EVP_CIPHER_CTX, EVP_CIPHER_CTX_free) OSSL_MAKE_DELETER(EVP_PKEY_CTX, EVP_PKEY_CTX_free) OSSL_MAKE_DELETER(EVP_PKEY, EVP_PKEY_free) +OSSL_MAKE_DELETER(CMAC_CTX, CMAC_CTX_free) // OpenSSL 1.0.x has different APIs for EVP_MD_CTX and HMAC // We need to add more custom logic to HMAC to let it properly delete the diff --git a/tool/speed.cc b/tool/speed.cc index 3c67795c9d..c95a967dd4 100644 --- a/tool/speed.cc +++ b/tool/speed.cc @@ -34,6 +34,8 @@ #include "internal.h" #include + +#include "openssl/cmac.h" #if defined(OPENSSL_IS_AWSLC) #include "bssl_bm.h" #include "../crypto/internal.h" @@ -1262,6 +1264,70 @@ static bool SpeedHmacOneShot(const EVP_MD *md, const std::string &name, return true; } +#if !defined(OPENSSL_1_0_BENCHMARK) +static bool SpeedCmacChunk(const EVP_CIPHER *cipher, std::string name, + size_t chunk_len) { + BM_NAMESPACE::UniquePtr ctx(CMAC_CTX_new()); + std::unique_ptr input(new uint8_t[chunk_len]); + const size_t key_len = EVP_CIPHER_key_length(cipher); + std::unique_ptr key(new uint8_t[key_len]); + BM_memset(key.get(), 0, key_len); + + if (!CMAC_Init(ctx.get(), key.get(), key_len, cipher, NULL /* ENGINE */)) { + fprintf(stderr, "Failed to create CMAC_CTX.\n"); + } + TimeResults results; + if (!TimeFunction(&results, [&ctx, chunk_len, &input]() -> bool { + uint8_t digest[EVP_MAX_MD_SIZE]; + size_t out_len; + + return +#if defined(OPENSSL_IS_AWSLC) || defined(OPENSSL_IS_BORINGSSL) + CMAC_Reset(ctx.get()) && +#else + CMAC_Init(ctx.get(), nullptr, 0, nullptr, nullptr /* ENGINE */) && +#endif + CMAC_Update(ctx.get(), input.get(), chunk_len) && + CMAC_Final(ctx.get(), digest, &out_len); + })) { + fprintf(stderr, "CMAC_Final failed.\n"); + ERR_print_errors_fp(stderr); + return false; + } + + results.PrintWithBytes(name, chunk_len); + return true; +} + +static bool SpeedCmac(const EVP_CIPHER *cipher, const std::string &name, const std::string &selected) { + if (!selected.empty() && name.find(selected) == std::string::npos) { + return true; + } + TimeResults results; + const size_t key_len = EVP_CIPHER_key_length(cipher); + std::unique_ptr key(new uint8_t[key_len]); + BM_memset(key.get(), 0, key_len); + BM_NAMESPACE::UniquePtr ctx(CMAC_CTX_new()); + if (!TimeFunction(&results, [&]() -> bool { + return CMAC_Init(ctx.get(), key.get(), key_len, cipher, + nullptr /* ENGINE */); + })) { + fprintf(stderr, "CMAC_Init failed.\n"); + ERR_print_errors_fp(stderr); + return false; + } + results.Print(name + " init"); + + for (size_t chunk_len : g_chunk_lengths) { + if (!SpeedCmacChunk(cipher, name, chunk_len)) { + return false; + } + } + + return true; +} + +#endif using RandomFunction = std::function; static bool SpeedRandomChunk(RandomFunction function, std::string name, size_t chunk_len) { @@ -2832,6 +2898,10 @@ bool Speed(const std::vector &args) { !SpeedHmacOneShot(EVP_sha256(), "HMAC-SHA256-OneShot", selected) || !SpeedHmacOneShot(EVP_sha384(), "HMAC-SHA384-OneShot", selected) || !SpeedHmacOneShot(EVP_sha512(), "HMAC-SHA512-OneShot", selected) || +#if !defined(OPENSSL_1_0_BENCHMARK) + !SpeedCmac(EVP_aes_128_cbc(), "CMAC-AES-128-CBC", selected) || + !SpeedCmac(EVP_aes_256_cbc(), "CMAC-AES-256-CBC", selected) || +#endif !SpeedRandom(RAND_bytes, "RNG", selected) || !SpeedECDH(selected) || !SpeedECDSA(selected) ||