Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package aws-c-cal for openSUSE:Factory checked in at 2025-03-13 15:06:13 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/aws-c-cal (Old) and /work/SRC/openSUSE:Factory/.aws-c-cal.new.19136 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "aws-c-cal" Thu Mar 13 15:06:13 2025 rev:14 rq:1252417 version:0.8.5 Changes: -------- --- /work/SRC/openSUSE:Factory/aws-c-cal/aws-c-cal.changes 2025-02-10 17:53:19.412016170 +0100 +++ /work/SRC/openSUSE:Factory/.aws-c-cal.new.19136/aws-c-cal.changes 2025-03-13 15:07:16.172898123 +0100 @@ -1,0 +2,8 @@ +Wed Mar 12 07:18:32 UTC 2025 - John Paul Adrian Glaubitz <adrian.glaub...@suse.com> + +- Update to version 0.8.5 + * Do not include crypto when doing byo_crypto by @DmitriyMusatkin in (#207) +- from version 0.8.4 + * Ed25519 support. by @DmitriyMusatkin in (#206) + +------------------------------------------------------------------- Old: ---- v0.8.3.tar.gz New: ---- v0.8.5.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ aws-c-cal.spec ++++++ --- /var/tmp/diff_new_pack.8WZVry/_old 2025-03-13 15:07:18.805008528 +0100 +++ /var/tmp/diff_new_pack.8WZVry/_new 2025-03-13 15:07:18.805008528 +0100 @@ -19,7 +19,7 @@ %define library_version 1.0.0 %define library_soversion 0unstable Name: aws-c-cal -Version: 0.8.3 +Version: 0.8.5 Release: 0 Summary: AWS C99 wrapper for cryptography primitives License: Apache-2.0 ++++++ v0.8.3.tar.gz -> v0.8.5.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-cal-0.8.3/.github/workflows/ci.yml new/aws-c-cal-0.8.5/.github/workflows/ci.yml --- old/aws-c-cal-0.8.3/.github/workflows/ci.yml 2025-01-29 19:14:48.000000000 +0100 +++ new/aws-c-cal-0.8.5/.github/workflows/ci.yml 2025-03-05 01:40:09.000000000 +0100 @@ -180,6 +180,19 @@ python -c "from urllib.request import urlretrieve; urlretrieve('${{ env.BUILDER_HOST }}/${{ env.BUILDER_SOURCE }}/${{ env.BUILDER_VERSION }}/builder.pyz?run=${{ env.RUN }}', 'builder.pyz')" python builder.pyz build -p ${{ env.PACKAGE_NAME }} + windows-ed25519: + runs-on: windows-2022 # latest + steps: + - uses: ilammy/setup-nasm@v1 + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ env.CRT_CI_ROLE }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} + - name: Build ${{ env.PACKAGE_NAME }} + consumers + run: | + python -c "from urllib.request import urlretrieve; urlretrieve('${{ env.BUILDER_HOST }}/${{ env.BUILDER_SOURCE }}/${{ env.BUILDER_VERSION }}/builder.pyz?run=${{ env.RUN }}', 'builder.pyz')" + python builder.pyz build -p ${{ env.PACKAGE_NAME }} --variant=aws-lc-ed25519 --cmake-extra=-DAWS_USE_LIBCRYPTO_TO_SUPPORT_ED25519_EVERYWHERE=ON + windows-debug: runs-on: windows-2022 # latest steps: @@ -235,7 +248,11 @@ python .\aws-c-cal\build\deps\aws-c-common\scripts\appverifier_ctest.py --build_directory .\aws-c-cal\build\aws-c-cal macos: - runs-on: macos-14 # latest + strategy: + matrix: + image: [macos-14-large, macos-14] + name: ${{ matrix.image == 'macos-14' && 'macos' || 'macos-x64' }} + runs-on: ${{ matrix.image }} steps: - uses: aws-actions/configure-aws-credentials@v4 with: @@ -247,8 +264,12 @@ chmod a+x builder ./builder build -p ${{ env.PACKAGE_NAME }} - macos-x64: - runs-on: macos-14-large # latest + macos-ed25519: + strategy: + matrix: + image: [macos-14-large, macos-14] + name: ${{ matrix.image == 'macos-14' && 'macos' || 'macos-x64' }} with lc ed25519 + runs-on: ${{ matrix.image }} steps: - uses: aws-actions/configure-aws-credentials@v4 with: @@ -258,7 +279,7 @@ run: | python3 -c "from urllib.request import urlretrieve; urlretrieve('${{ env.BUILDER_HOST }}/${{ env.BUILDER_SOURCE }}/${{ env.BUILDER_VERSION }}/builder.pyz', 'builder')" chmod a+x builder - ./builder build -p ${{ env.PACKAGE_NAME }} + ./builder build -p ${{ env.PACKAGE_NAME }} --variant=aws-lc-ed25519 --cmake-extra=-DAWS_USE_LIBCRYPTO_TO_SUPPORT_ED25519_EVERYWHERE=ON macos-min-deployment-target: runs-on: macos-14 # latest @@ -303,11 +324,11 @@ aws-region: ${{ env.AWS_DEFAULT_REGION }} - uses: actions/checkout@v4 - name: Build ${{ env.PACKAGE_NAME }} + consumers - uses: cross-platform-actions/action@v0.25.0 + uses: cross-platform-actions/action@v0.27.0 with: operating_system: openbsd architecture: x86-64 - version: '7.4' + version: '7.6' shell: bash run: | sudo pkg_add py3-urllib3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-cal-0.8.3/CMakeLists.txt new/aws-c-cal-0.8.5/CMakeLists.txt --- old/aws-c-cal-0.8.3/CMakeLists.txt 2025-01-29 19:14:48.000000000 +0100 +++ new/aws-c-cal-0.8.5/CMakeLists.txt 2025-03-05 01:40:09.000000000 +0100 @@ -10,6 +10,7 @@ option(BYO_CRYPTO "Set this if you want to provide your own cryptography implementation. This will cause the defaults to not be compiled." OFF) option(USE_OPENSSL "Set this if you want to use your system's OpenSSL 1.0.2/1.1.1 compatible libcrypto" OFF) option(AWS_USE_CRYPTO_SHARED_LIBS "Force c-cal to use shared libs in Findcrypto" OFF) +option(AWS_USE_LIBCRYPTO_TO_SUPPORT_ED25519_EVERYWHERE "Experimental feature to support ED25519 keygen on platforms that do not support it in os libs (i.e. win/mac)" OFF) if (NOT IN_SOURCE_BUILD) # this is required so we can use aws-c-common's CMake modules @@ -26,11 +27,11 @@ include(GNUInstallDirs) file(GLOB AWS_CAL_HEADERS - "include/aws/cal/*.h" + "include/aws/cal/*.h" ) file(GLOB AWS_CAL_SRC - "source/*.c" + "source/*.c" ) if (WIN32) @@ -39,6 +40,14 @@ file(GLOB AWS_CAL_OS_SRC "source/windows/*.c" ) + + if (AWS_USE_LIBCRYPTO_TO_SUPPORT_ED25519_EVERYWHERE) + list(APPEND AWS_CAL_OS_SRC "source/shared/ed25519_lc.c") + list(APPEND AWS_CAL_OS_SRC "source/shared/lccrypto_common.c") + else() + list(APPEND AWS_CAL_OS_SRC "source/shared/ed25519_noop.c") + endif() + if (AWS_SUPPORT_WIN7) set(PLATFORM_LIBS bcrypt) else() @@ -55,9 +64,16 @@ elseif (APPLE) if (NOT BYO_CRYPTO) file(GLOB AWS_CAL_OS_SRC - "source/darwin/*.c" + "source/darwin/*.c" ) + if (AWS_USE_LIBCRYPTO_TO_SUPPORT_ED25519_EVERYWHERE) + list(APPEND AWS_CAL_OS_SRC "source/shared/ed25519_lc.c") + list(APPEND AWS_CAL_OS_SRC "source/shared/lccrypto_common.c") + else() + list(APPEND AWS_CAL_OS_SRC "source/shared/ed25519_noop.c") + endif() + find_library(SECURITY_LIB Security) if (NOT SECURITY_LIB) message(FATAL_ERROR "Security Framework not found") @@ -75,20 +91,27 @@ if (NOT BYO_CRYPTO) file(GLOB AWS_CAL_OS_SRC "source/unix/*.c" + "source/shared/ed25519_lc.c" + "source/shared/lccrypto_common.c" ) + endif() +endif() + +if (NOT BYO_CRYPTO) + if ((NOT WIN32 AND NOT APPLE) OR AWS_USE_LIBCRYPTO_TO_SUPPORT_ED25519_EVERYWHERE) if (USE_OPENSSL AND NOT ANDROID) find_package(OpenSSL REQUIRED) find_package(Threads REQUIRED) - set(PLATFORM_LIBS OpenSSL::Crypto Threads::Threads) + list(APPEND PLATFORM_LIBS OpenSSL::Crypto Threads::Threads) message(STATUS "Using libcrypto from system: ${OPENSSL_CRYPTO_LIBRARY}") elseif(NOT USE_OPENSSL AND IN_SOURCE_BUILD) if (TARGET crypto) message(STATUS "Using libcrypto from AWS-LC") - set(PLATFORM_LIBS crypto) + list(APPEND PLATFORM_LIBS crypto) elseif(AWSLC_PREBUILT) message(STATUS "Using prebuilt libcrypto from AWS-LC") find_package(crypto REQUIRED) - set(PLATFORM_LIBS AWS::crypto) + list(APPEND PLATFORM_LIBS AWS::crypto) else() message(FATAL_ERROR "Target crypto is not defined, failed to find libcrypto.") endif() @@ -96,22 +119,22 @@ # note aws_use_package() does this for you, except it appends to the public link targets # which we probably don't want for this case where we want the crypto dependency private if (IN_SOURCE_BUILD) - set(PLATFORM_LIBS crypto) + list(APPEND PLATFORM_LIBS crypto) else() find_package(crypto REQUIRED) - set(PLATFORM_LIBS AWS::crypto) + list(APPEND PLATFORM_LIBS AWS::crypto) endif() endif() endif() endif() file(GLOB CAL_HEADERS - ${AWS_CAL_HEADERS} + ${AWS_CAL_HEADERS} ) file(GLOB CAL_SRC - ${AWS_CAL_SRC} - ${AWS_CAL_OS_SRC} + ${AWS_CAL_SRC} + ${AWS_CAL_OS_SRC} ) add_library(${PROJECT_NAME} ${CAL_SRC}) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-cal-0.8.3/builder.json new/aws-c-cal-0.8.5/builder.json --- old/aws-c-cal-0.8.3/builder.json 2025-01-29 19:14:48.000000000 +0100 +++ new/aws-c-cal-0.8.5/builder.json 2025-03-05 01:40:09.000000000 +0100 @@ -103,6 +103,24 @@ } } }, + "aws-lc-ed25519": { + "targets": { + "windows": { + "+upstream": [ + { + "name": "aws-lc" + } + ] + }, + "macos": { + "+upstream": [ + { + "name": "aws-lc" + } + ] + } + } + }, "no-tests": { "!test_steps": [] }, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-cal-0.8.3/include/aws/cal/cal.h new/aws-c-cal-0.8.5/include/aws/cal/cal.h --- old/aws-c-cal-0.8.3/include/aws/cal/cal.h 2025-01-29 19:14:48.000000000 +0100 +++ new/aws-c-cal-0.8.5/include/aws/cal/cal.h 2025-03-05 01:40:09.000000000 +0100 @@ -40,6 +40,7 @@ AWS_LS_CAL_DER, AWS_LS_CAL_LIBCRYPTO_RESOLVE, AWS_LS_CAL_RSA, + AWS_LS_CAL_ED25519, AWS_LS_CAL_LAST = AWS_LOG_SUBJECT_END_RANGE(AWS_C_CAL_PACKAGE_ID) }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-cal-0.8.3/include/aws/cal/ed25519.h new/aws-c-cal-0.8.5/include/aws/cal/ed25519.h --- old/aws-c-cal-0.8.3/include/aws/cal/ed25519.h 1970-01-01 01:00:00.000000000 +0100 +++ new/aws-c-cal-0.8.5/include/aws/cal/ed25519.h 2025-03-05 01:40:09.000000000 +0100 @@ -0,0 +1,88 @@ +#ifndef AWS_CAL_ED25519_H +#define AWS_CAL_ED25519_H +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +#include <aws/cal/cal.h> +#include <aws/common/byte_buf.h> + +AWS_PUSH_SANE_WARNING_LEVEL + +struct aws_ed25519_key_pair; + +AWS_EXTERN_C_BEGIN + +/** + * Generate new Ed25519 key. + * Returns a new instance of aws_ed25519_key_pair if the key was successfully generated. + * Otherwise returns NULL. + * Note: keygen is not supported on all platforms and will return NULL for the key + * and raise AWS_ERROR_CAL_UNSUPPORTED_ALGORITHM. + * Examples of unsupported cases: + * - openssl pre 1.1.1 (Note: aws-lc and boringssl both expose the needed functions) + * - win/mac builds without special flag that forces linking to libcrypto to support this + */ +AWS_CAL_API struct aws_ed25519_key_pair *aws_ed25519_key_pair_new_generate(struct aws_allocator *allocator); + +/** + * Adds one to an Ed25519 key pair's ref count. + * Returns key_pair pointer. + */ +AWS_CAL_API struct aws_ed25519_key_pair *aws_ed25519_key_pair_acquire(struct aws_ed25519_key_pair *key_pair); + +/** + * Subtracts one from an Ed25519 key pair's ref count. If ref count reaches zero, the key pair is destroyed. + * Always returns NULL. + */ +AWS_CAL_API struct aws_ed25519_key_pair *aws_ed25519_key_pair_release(struct aws_ed25519_key_pair *key_pair); + +enum aws_ed25519_key_export_format { + /* Export the key as raw bytes */ + AWS_CAL_ED25519_KEY_EXPORT_RAW, + + /** + * Export the key to openssh format. + * This will only export the key block, framing (i.e. pem) is left as exercise for the caller. + * b64 encoding is done as convenience since common framing formats require it. + */ + AWS_CAL_ED25519_KEY_EXPORT_OPENSSH_B64, +}; + +/* + * Get public key for the key pair. + * Key in specified format is appended to the buffer. + * The buffer must be initialized before this call, with sufficient capacity to hold the result. + * Use aws_ed25519_key_pair_get_public_key_size to figure out how much capacity buffer needs for a given format. + */ +AWS_CAL_API int aws_ed25519_key_pair_get_public_key( + const struct aws_ed25519_key_pair *key_pair, + enum aws_ed25519_key_export_format format, + struct aws_byte_buf *out); + +/** + * Gets the size of the exported public key. + */ +AWS_CAL_API size_t aws_ed25519_key_pair_get_public_key_size(enum aws_ed25519_key_export_format format); + +/* + * Get private key for the key pair. + * Key in specified format is appended to the buffer. + * The buffer must be initialized before this call, with sufficient capacity to hold the result. + * Use aws_ed25519_key_pair_get_private_key_size to figure out how much capacity buffer needs for a given format. + */ +AWS_CAL_API int aws_ed25519_key_pair_get_private_key( + const struct aws_ed25519_key_pair *key_pair, + enum aws_ed25519_key_export_format format, + struct aws_byte_buf *out); + +/** + * Gets the size of the exported private key. + */ +AWS_CAL_API size_t aws_ed25519_key_pair_get_private_key_size(enum aws_ed25519_key_export_format format); + +AWS_EXTERN_C_END + +AWS_POP_SANE_WARNING_LEVEL + +#endif /* AWS_CAL_ED25519_H */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-cal-0.8.3/include/aws/cal/private/opensslcrypto_common.h new/aws-c-cal-0.8.5/include/aws/cal/private/opensslcrypto_common.h --- old/aws-c-cal-0.8.3/include/aws/cal/private/opensslcrypto_common.h 2025-01-29 19:14:48.000000000 +0100 +++ new/aws-c-cal-0.8.5/include/aws/cal/private/opensslcrypto_common.h 2025-03-05 01:40:09.000000000 +0100 @@ -6,6 +6,8 @@ * SPDX-License-Identifier: Apache-2.0. */ +#include <aws/cal/cal.h> + #define OPENSSL_SUPPRESS_DEPRECATED #include <openssl/crypto.h> #include <openssl/evp.h> @@ -77,4 +79,6 @@ extern struct openssl_evp_md_ctx_table *g_aws_openssl_evp_md_ctx_table; +int aws_reinterpret_lc_evp_error_as_crt(int evp_error, const char *function_name, enum aws_cal_log_subject subject); + #endif /* AWS_C_CAL_OPENSSLCRYPTO_COMMON_H */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-cal-0.8.3/source/cal.c new/aws-c-cal-0.8.5/source/cal.c --- old/aws-c-cal-0.8.3/source/cal.c 2025-01-29 19:14:48.000000000 +0100 +++ new/aws-c-cal-0.8.5/source/cal.c 2025-03-05 01:40:09.000000000 +0100 @@ -67,6 +67,7 @@ "libcrypto_resolve", "Subject for libcrypto symbol resolution logging."), DEFINE_LOG_SUBJECT_INFO(AWS_LS_CAL_RSA, "rsa", "Subject for rsa cryptography specific logging."), + DEFINE_LOG_SUBJECT_INFO(AWS_LS_CAL_ED25519, "ed25519", "Subject for ed25519 cryptography specific logging."), }; static struct aws_log_subject_info_list s_cal_log_subject_list = { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-cal-0.8.3/source/darwin/commoncrypto_platform_init.c new/aws-c-cal-0.8.5/source/darwin/commoncrypto_platform_init.c --- old/aws-c-cal-0.8.3/source/darwin/commoncrypto_platform_init.c 2025-01-29 19:14:48.000000000 +0100 +++ new/aws-c-cal-0.8.5/source/darwin/commoncrypto_platform_init.c 2025-03-05 01:40:09.000000000 +0100 @@ -4,11 +4,28 @@ */ #include <aws/common/allocator.h> +#if defined(AWS_USE_LIBCRYPTO_TO_SUPPORT_ED25519_EVERYWHERE) && defined(OPENSSL_IS_AWSLC) +# include <openssl/thread.h> +#endif void aws_cal_platform_init(struct aws_allocator *allocator) { (void)allocator; } -void aws_cal_platform_clean_up(void) {} +#if defined(AWS_USE_LIBCRYPTO_TO_SUPPORT_ED25519_EVERYWHERE) && defined(OPENSSL_IS_AWSLC) +void __attribute__((destructor)) s_cal_crypto_shutdown(void) { + AWSLC_thread_local_shutdown(); +} +#endif + +void aws_cal_platform_clean_up(void) { +#if defined(AWS_USE_LIBCRYPTO_TO_SUPPORT_ED25519_EVERYWHERE) && defined(OPENSSL_IS_AWSLC) + AWSLC_thread_local_clear(); +#endif +} -void aws_cal_platform_thread_clean_up(void) {} +void aws_cal_platform_thread_clean_up(void) { +#if defined(AWS_USE_LIBCRYPTO_TO_SUPPORT_ED25519_EVERYWHERE) && defined(OPENSSL_IS_AWSLC) + AWSLC_thread_local_clear(); +#endif +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-cal-0.8.3/source/ed25519.c new/aws-c-cal-0.8.5/source/ed25519.c --- old/aws-c-cal-0.8.3/source/ed25519.c 1970-01-01 01:00:00.000000000 +0100 +++ new/aws-c-cal-0.8.5/source/ed25519.c 2025-03-05 01:40:09.000000000 +0100 @@ -0,0 +1,147 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/cal/ed25519.h> +#include <aws/common/ref_count.h> + +struct aws_ed25519_key_pair_impl; + +#ifndef BYO_CRYPTO + +extern struct aws_ed25519_key_pair_impl *aws_ed25519_key_pair_new_generate_impl(struct aws_allocator *allocator); + +extern void aws_ed25519_key_pair_destroy_impl(struct aws_ed25519_key_pair_impl *key_pair_impl); + +extern int aws_ed25519_key_pair_get_public_key_impl( + const struct aws_ed25519_key_pair_impl *key_pair, + enum aws_ed25519_key_export_format format, + struct aws_byte_buf *out); + +extern size_t aws_ed25519_key_pair_get_public_key_size_impl(enum aws_ed25519_key_export_format format); + +extern int aws_ed25519_key_pair_get_private_key_impl( + const struct aws_ed25519_key_pair_impl *key_pair, + enum aws_ed25519_key_export_format format, + struct aws_byte_buf *out); + +extern size_t aws_ed25519_key_pair_get_private_key_size_impl(enum aws_ed25519_key_export_format format); + +#else /* BYO_CRYPTO */ + +struct aws_ed25519_key_pair_impl *aws_ed25519_key_pair_new_generate_impl(struct aws_allocator *allocator) { + (void)allocator; + abort(); +} + +void aws_ed25519_key_pair_destroy_impl(struct aws_ed25519_key_pair_impl *key_pair_impl) { + (void)key_pair_impl; + abort(); +} + +int aws_ed25519_key_pair_get_public_key_impl( + const struct aws_ed25519_key_pair_impl *key_pair, + enum aws_ed25519_key_export_format format, + struct aws_byte_buf *out) { + (void)key_pair; + (void)format; + (void)out; + abort(); +} + +size_t aws_ed25519_key_pair_get_public_key_size_impl(enum aws_ed25519_key_export_format format) { + (void)format; + abort(); +} + +int aws_ed25519_key_pair_get_private_key_impl( + const struct aws_ed25519_key_pair_impl *key_pair, + enum aws_ed25519_key_export_format format, + struct aws_byte_buf *out) { + (void)key_pair; + (void)format; + (void)out; + abort(); +} + +size_t aws_ed25519_key_pair_get_private_key_size_impl(enum aws_ed25519_key_export_format format) { + (void)format; + abort(); +} + +#endif /* BYO_CRYPTO */ + +struct aws_ed25519_key_pair { + struct aws_allocator *allocator; + struct aws_ref_count ref_count; + + struct aws_ed25519_key_pair_impl *key; +}; + +static void s_ed25519_destroy_key(void *key_pair) { + if (key_pair == NULL) { + return; + } + + struct aws_ed25519_key_pair *ed25519_key_pair = (struct aws_ed25519_key_pair *)(key_pair); + + if (ed25519_key_pair->key != NULL) { + aws_ed25519_key_pair_destroy_impl(ed25519_key_pair->key); + } + + aws_mem_release(ed25519_key_pair->allocator, ed25519_key_pair); +} + +struct aws_ed25519_key_pair *aws_ed25519_key_pair_new_generate(struct aws_allocator *allocator) { + + struct aws_ed25519_key_pair_impl *key_impl = aws_ed25519_key_pair_new_generate_impl(allocator); + + if (key_impl == NULL) { + return NULL; + } + + struct aws_ed25519_key_pair *key_pair = aws_mem_calloc(allocator, 1, sizeof(struct aws_ed25519_key_pair)); + + aws_ref_count_init(&key_pair->ref_count, key_pair, s_ed25519_destroy_key); + key_pair->allocator = allocator; + key_pair->key = key_impl; + + return key_pair; +} + +struct aws_ed25519_key_pair *aws_ed25519_key_pair_acquire(struct aws_ed25519_key_pair *key_pair) { + if (key_pair != NULL) { + aws_ref_count_acquire(&key_pair->ref_count); + } + return key_pair; +} + +struct aws_ed25519_key_pair *aws_ed25519_key_pair_release(struct aws_ed25519_key_pair *key_pair) { + if (key_pair != NULL) { + aws_ref_count_release(&key_pair->ref_count); + } + return NULL; +} + +int aws_ed25519_key_pair_get_public_key( + const struct aws_ed25519_key_pair *key_pair, + enum aws_ed25519_key_export_format format, + struct aws_byte_buf *out) { + return aws_ed25519_key_pair_get_public_key_impl(key_pair->key, format, out); +} + +size_t aws_ed25519_key_pair_get_public_key_size(enum aws_ed25519_key_export_format format) { + return aws_ed25519_key_pair_get_public_key_size_impl(format); +} + +int aws_ed25519_key_pair_get_private_key( + const struct aws_ed25519_key_pair *key_pair, + enum aws_ed25519_key_export_format format, + struct aws_byte_buf *out) { + return aws_ed25519_key_pair_get_private_key_impl(key_pair->key, format, out); +} + +size_t aws_ed25519_key_pair_get_private_key_size(enum aws_ed25519_key_export_format format) { + return aws_ed25519_key_pair_get_private_key_size_impl(format); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-cal-0.8.3/source/shared/ed25519_lc.c new/aws-c-cal-0.8.5/source/shared/ed25519_lc.c --- old/aws-c-cal-0.8.3/source/shared/ed25519_lc.c 1970-01-01 01:00:00.000000000 +0100 +++ new/aws-c-cal-0.8.5/source/shared/ed25519_lc.c 2025-03-05 01:40:09.000000000 +0100 @@ -0,0 +1,372 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/cal/ed25519.h> +#include <aws/cal/private/opensslcrypto_common.h> + +#include <aws/common/device_random.h> +#include <aws/common/encoding.h> + +#include <openssl/evp.h> + +struct aws_ed25519_key_pair_impl { + struct aws_allocator *allocator; + EVP_PKEY *key; +}; + +int aws_ed25519_key_pair_get_private_key_impl( + const struct aws_ed25519_key_pair_impl *key_pair, + enum aws_ed25519_key_export_format format, + struct aws_byte_buf *out); + +int aws_ed25519_key_pair_get_public_key_impl( + const struct aws_ed25519_key_pair_impl *key_pair, + enum aws_ed25519_key_export_format format, + struct aws_byte_buf *out); + +static const size_t s_private_key_size = 32; +static const size_t s_public_key_size = 32; + +int s_byte_buf_write_be32_with_err(struct aws_byte_buf *buf, uint32_t x) { + return aws_byte_buf_write_be32(buf, x) ? AWS_OP_SUCCESS : AWS_ERROR_SHORT_BUFFER; +} + +void aws_ed25519_key_pair_destroy_impl(struct aws_ed25519_key_pair_impl *key_pair) { + if (key_pair == NULL) { + return; + } + + if (key_pair->key != NULL) { + EVP_PKEY_free(key_pair->key); + } + + aws_mem_release(key_pair->allocator, key_pair); +} + +struct aws_ed25519_key_pair_impl *aws_ed25519_key_pair_new_generate_impl(struct aws_allocator *allocator) { +#if defined(OPENSSL_IS_OPENSSL) && OPENSSL_VERSION_NUMBER <= 0x10101000L + /* ed25519 support does not exist prior to 1.1.1 */ + aws_raise_error(AWS_ERROR_CAL_UNSUPPORTED_ALGORITHM); + return NULL; +#else + EVP_PKEY *pkey = NULL; + + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, NULL); + if (ctx == NULL) { + aws_raise_error(AWS_ERROR_CAL_CRYPTO_OPERATION_FAILED); + return NULL; + } + + if (aws_reinterpret_lc_evp_error_as_crt(EVP_PKEY_keygen_init(ctx), "EVP_PKEY_keygen_init", AWS_LS_CAL_ED25519)) { + goto on_error; + } + + if (aws_reinterpret_lc_evp_error_as_crt(EVP_PKEY_keygen(ctx, &pkey), "EVP_PKEY_keygen", AWS_LS_CAL_ED25519)) { + goto on_error; + } + + struct aws_ed25519_key_pair_impl *key_pair = aws_mem_calloc(allocator, 1, sizeof(struct aws_ed25519_key_pair_impl)); + key_pair->key = pkey; + key_pair->allocator = allocator; + + EVP_PKEY_CTX_free(ctx); + return key_pair; + +on_error: + EVP_PKEY_CTX_free(ctx); + return NULL; +#endif +} + +static struct aws_byte_cursor s_key_type_literal = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("ssh-ed25519"); + +int s_ed25519_openssh_encode_public_key(const struct aws_ed25519_key_pair_impl *key_pair, struct aws_byte_buf *out) { + if (s_byte_buf_write_be32_with_err(out, (uint32_t)s_key_type_literal.len) != AWS_OP_SUCCESS || + aws_byte_buf_append(out, &s_key_type_literal) != AWS_OP_SUCCESS) { + return AWS_OP_ERR; + } + + if (s_byte_buf_write_be32_with_err(out, 32) != AWS_OP_SUCCESS || + aws_ed25519_key_pair_get_public_key_impl(key_pair, AWS_CAL_ED25519_KEY_EXPORT_RAW, out) != AWS_OP_SUCCESS) { + return AWS_OP_ERR; + } + + return AWS_OP_SUCCESS; +} + +/** + * format here is b64 of the following structure + * string "ssh-ed25519" #literal + * string key + * Note: string is always u32 size followed by the data. all multibyte ints are in big-endian + */ +int s_ed25519_export_public_openssh(const struct aws_ed25519_key_pair_impl *key_pair, struct aws_byte_buf *out) { + uint8_t key_data[4 /*id len*/ + 11 /* ssh-ed25519 literal */ + 4 /*key len*/ + 32 /* key */] = {0}; + struct aws_byte_buf key_buf = aws_byte_buf_from_empty_array(key_data, AWS_ARRAY_SIZE(key_data)); + + if (s_ed25519_openssh_encode_public_key(key_pair, &key_buf)) { + return AWS_OP_ERR; + } + + struct aws_byte_cursor key_cur = aws_byte_cursor_from_buf(&key_buf); + + if (aws_base64_encode(&key_cur, out) != AWS_OP_SUCCESS) { + return AWS_OP_ERR; + } + + return AWS_OP_SUCCESS; +} + +int s_ed25519_export_public_raw(const struct aws_ed25519_key_pair_impl *key_pair, struct aws_byte_buf *out) { + size_t remaining = out->capacity - out->len; + if (remaining < s_public_key_size) { + return aws_raise_error(AWS_ERROR_SHORT_BUFFER); + } + + if (aws_reinterpret_lc_evp_error_as_crt( + EVP_PKEY_get_raw_public_key(key_pair->key, out->buffer + out->len, &remaining), + "EVP_PKEY_get_raw_public_key", + AWS_LS_CAL_ED25519)) { + return aws_raise_error(AWS_ERROR_CAL_CRYPTO_OPERATION_FAILED); + } + if (remaining != s_public_key_size) { + return aws_raise_error(AWS_ERROR_CAL_CRYPTO_OPERATION_FAILED); + } + out->len += s_public_key_size; + + return AWS_OP_SUCCESS; +} + +int aws_ed25519_key_pair_get_public_key_impl( + const struct aws_ed25519_key_pair_impl *key_pair, + enum aws_ed25519_key_export_format format, + struct aws_byte_buf *out) { + AWS_PRECONDITION(key_pair); + AWS_PRECONDITION(aws_byte_buf_is_valid(out)); + + switch (format) { + case AWS_CAL_ED25519_KEY_EXPORT_RAW: + return s_ed25519_export_public_raw(key_pair, out); + case AWS_CAL_ED25519_KEY_EXPORT_OPENSSH_B64: + return s_ed25519_export_public_openssh(key_pair, out); + default: + return aws_raise_error(AWS_ERROR_CAL_UNSUPPORTED_KEY_FORMAT); + } +} + +size_t aws_ed25519_key_pair_get_public_key_size_impl(enum aws_ed25519_key_export_format format) { + switch (format) { + case AWS_CAL_ED25519_KEY_EXPORT_RAW: + return s_public_key_size; + case AWS_CAL_ED25519_KEY_EXPORT_OPENSSH_B64: + return 68; + default: + aws_raise_error(AWS_ERROR_CAL_UNSUPPORTED_KEY_FORMAT); + return 0; + } +} + +static struct aws_byte_cursor s_private_magic = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("openssh-key-v1"); +static struct aws_byte_cursor s_private_none_literal = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("none"); + +/** + * Openssl only added helpers for this format in 3.0 so we are out of luck with lc and boringssl. + * Hence lets just implement export ourselves. + * Some of the spec features (encryption, comments) are not supported. + * High level format is: + * string "openssh-key-v1\0" #literal + * string cipher #literal none since we dont support enc + * string kdf #literal none since we dont support enc + * string kdf options #empty since we dont support enc + * u32 num keys + * string public key #openssh encoded version + * string private key blob + * - u32 check #random num + * - u32 check #same check repeated + * - string "ssh-ed25519" #literal + * - string raw pub key + * - string raw priv key + * - string comment # no comment for now + * - padding to 8 bytes # just add bytes 1, 2, 3, ... until priv block is divisible by 8 + * Note: string is always u32 size followed by the data. all multibyte ints are in big-endian + */ +int s_ed25519_export_private_openssh(const struct aws_ed25519_key_pair_impl *key_pair, struct aws_byte_buf *out) { + + struct aws_byte_buf key_buf; + aws_byte_buf_init(&key_buf, key_pair->allocator, 312); + + /* magic */ + if (aws_byte_buf_append(&key_buf, &s_private_magic) != AWS_OP_SUCCESS) { + goto on_error; + } + if (!aws_byte_buf_write_u8(&key_buf, 0)) { + aws_raise_error(AWS_ERROR_SHORT_BUFFER); + goto on_error; + } + + /* cipher name (we dont support it now, but still need to write out 0) */ + if (s_byte_buf_write_be32_with_err(&key_buf, 4) != AWS_OP_SUCCESS || + aws_byte_buf_append(&key_buf, &s_private_none_literal) != AWS_OP_SUCCESS) { + goto on_error; + } + + /* kdf name (we dont support it now, but still need to write out 0) */ + if (s_byte_buf_write_be32_with_err(&key_buf, 4) != AWS_OP_SUCCESS || + aws_byte_buf_append(&key_buf, &s_private_none_literal) != AWS_OP_SUCCESS) { + goto on_error; + } + + /* kdf options (we dont support it now, but still need to write out 0) */ + if (s_byte_buf_write_be32_with_err(&key_buf, 0) != AWS_OP_SUCCESS) { + goto on_error; + } + + /* number of keys */ + if (s_byte_buf_write_be32_with_err(&key_buf, 1) != AWS_OP_SUCCESS) { + goto on_error; + } + + /* encoded public key */ + const size_t pub_encoded_len = 4 /*id len*/ + 11 /* ssh-ed25519 literal */ + 4 /*key len*/ + 32 /* key */; + if (s_byte_buf_write_be32_with_err(&key_buf, (uint32_t)pub_encoded_len) != AWS_OP_SUCCESS || + s_ed25519_openssh_encode_public_key(key_pair, &key_buf) != AWS_OP_SUCCESS) { + goto on_error; + } + + size_t priv_block_len = 4 + /* check1 */ + 4 + /* check2 */ + 4 + s_key_type_literal.len + /* key type string */ + 4 + s_public_key_size + /* public key */ + 4 + s_private_key_size + s_public_key_size + /* private key (includes public) */ + 4 + 0; /* comment (0, since comment not currently supported) */ + + /* pad block to the next multiple of 8 */ + size_t priv_block_padded_len = (priv_block_len + 7) & ~7; + + if (s_byte_buf_write_be32_with_err(&key_buf, (uint32_t)priv_block_padded_len) != AWS_OP_SUCCESS) { + goto on_error; + } + + uint32_t check = 0; + if (aws_device_random_u32(&check) != AWS_OP_SUCCESS) { + aws_raise_error(AWS_ERROR_RANDOM_GEN_FAILED); + goto on_error; + } + + /* check (and yeah its written twice on purpose) */ + if (s_byte_buf_write_be32_with_err(&key_buf, check) != AWS_OP_SUCCESS || + s_byte_buf_write_be32_with_err(&key_buf, check) != AWS_OP_SUCCESS) { + goto on_error; + } + + /* key type */ + if (s_byte_buf_write_be32_with_err(&key_buf, (uint32_t)s_key_type_literal.len) != AWS_OP_SUCCESS || + aws_byte_buf_append(&key_buf, &s_key_type_literal) != AWS_OP_SUCCESS) { + goto on_error; + } + + /* public key (raw) */ + if (s_byte_buf_write_be32_with_err(&key_buf, (uint32_t)s_public_key_size) != AWS_OP_SUCCESS || + aws_ed25519_key_pair_get_public_key_impl(key_pair, AWS_CAL_ED25519_KEY_EXPORT_RAW, &key_buf) != + AWS_OP_SUCCESS) { + goto on_error; + } + + /* private key - seed + pub (raw) */ + if (s_byte_buf_write_be32_with_err(&key_buf, (uint32_t)(s_private_key_size + s_public_key_size)) != + AWS_OP_SUCCESS || + aws_ed25519_key_pair_get_private_key_impl(key_pair, AWS_CAL_ED25519_KEY_EXPORT_RAW, &key_buf) != + AWS_OP_SUCCESS || + aws_ed25519_key_pair_get_public_key_impl(key_pair, AWS_CAL_ED25519_KEY_EXPORT_RAW, &key_buf) != + AWS_OP_SUCCESS) { + goto on_error; + } + + /* comment */ + if (s_byte_buf_write_be32_with_err(&key_buf, 0) != AWS_OP_SUCCESS) { + aws_raise_error(AWS_ERROR_SHORT_BUFFER); + goto on_error; + } + + /* padding */ + for (uint8_t i = 1; i < (priv_block_padded_len - priv_block_len + 1); ++i) { + if (!aws_byte_buf_write_u8(&key_buf, i)) { + aws_raise_error(AWS_ERROR_SHORT_BUFFER); + goto on_error; + } + } + + struct aws_byte_cursor key_cur = aws_byte_cursor_from_buf(&key_buf); + + if (aws_base64_encode(&key_cur, out) != AWS_OP_SUCCESS) { + aws_byte_buf_clean_up(&key_buf); + return AWS_OP_ERR; + } + + aws_byte_buf_clean_up(&key_buf); + return AWS_OP_SUCCESS; + +on_error: + aws_byte_buf_clean_up(&key_buf); + return AWS_OP_ERR; +} + +int s_ed25519_export_private_raw(const struct aws_ed25519_key_pair_impl *key_pair, struct aws_byte_buf *out) { + size_t remaining = out->capacity - out->len; + if (remaining < s_private_key_size) { + return aws_raise_error(AWS_ERROR_SHORT_BUFFER); + } + + /** + * RFC defines private key to be 64 bytes (seed + pub). + * Old versions of openssl did return it that way, but at some point (seems to be around 1.1.1l) they switched to + * just returning seed. So for consistency lets also return just the seed. + * Which on older versions of openssl just means reading first 32 bytes. + */ + remaining = s_private_key_size; + + if (aws_reinterpret_lc_evp_error_as_crt( + EVP_PKEY_get_raw_private_key(key_pair->key, out->buffer + out->len, &remaining), + "EVP_PKEY_get_raw_private_key", + AWS_LS_CAL_ED25519)) { + return aws_raise_error(AWS_ERROR_CAL_CRYPTO_OPERATION_FAILED); + } + + if (remaining != s_private_key_size) { + return aws_raise_error(AWS_ERROR_CAL_CRYPTO_OPERATION_FAILED); + } + out->len += s_private_key_size; + + return AWS_OP_SUCCESS; +} + +int aws_ed25519_key_pair_get_private_key_impl( + const struct aws_ed25519_key_pair_impl *key_pair, + enum aws_ed25519_key_export_format format, + struct aws_byte_buf *out) { + AWS_PRECONDITION(key_pair); + AWS_PRECONDITION(aws_byte_buf_is_valid(out)); + + switch (format) { + case AWS_CAL_ED25519_KEY_EXPORT_RAW: + return s_ed25519_export_private_raw(key_pair, out); + case AWS_CAL_ED25519_KEY_EXPORT_OPENSSH_B64: + return s_ed25519_export_private_openssh(key_pair, out); + default: + return aws_raise_error(AWS_ERROR_CAL_UNSUPPORTED_KEY_FORMAT); + } +} + +size_t aws_ed25519_key_pair_get_private_key_size_impl(enum aws_ed25519_key_export_format format) { + switch (format) { + case AWS_CAL_ED25519_KEY_EXPORT_RAW: + return s_private_key_size; + case AWS_CAL_ED25519_KEY_EXPORT_OPENSSH_B64: + return 312; + default: + aws_raise_error(AWS_ERROR_CAL_UNSUPPORTED_KEY_FORMAT); + return 0; + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-cal-0.8.3/source/shared/ed25519_noop.c new/aws-c-cal-0.8.5/source/shared/ed25519_noop.c --- old/aws-c-cal-0.8.3/source/shared/ed25519_noop.c 1970-01-01 01:00:00.000000000 +0100 +++ new/aws-c-cal-0.8.5/source/shared/ed25519_noop.c 2025-03-05 01:40:09.000000000 +0100 @@ -0,0 +1,51 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/cal/ed25519.h> + +struct aws_ed25519_key_pair_impl; + +void aws_ed25519_key_pair_destroy_impl(struct aws_ed25519_key_pair_impl *key_pair) { + AWS_FATAL_ASSERT(key_pair == NULL); + return; +} + +struct aws_ed25519_key_pair_impl *aws_ed25519_key_pair_new_generate_impl(struct aws_allocator *allocator) { + (void)allocator; + aws_raise_error(AWS_ERROR_PLATFORM_NOT_SUPPORTED); + return NULL; +} + +int aws_ed25519_key_pair_get_public_key_impl( + const struct aws_ed25519_key_pair_impl *key_pair, + enum aws_ed25519_key_export_format format, + struct aws_byte_buf *out) { + (void)key_pair; + (void)format; + (void)out; + return aws_raise_error(AWS_ERROR_PLATFORM_NOT_SUPPORTED); +} + +size_t aws_ed25519_key_pair_get_public_key_size_impl(enum aws_ed25519_key_export_format format) { + (void)format; + AWS_FATAL_ASSERT(0); + return 0; +} + +int aws_ed25519_key_pair_get_private_key_impl( + const struct aws_ed25519_key_pair_impl *key_pair, + enum aws_ed25519_key_export_format format, + struct aws_byte_buf *out) { + (void)key_pair; + (void)format; + (void)out; + return aws_raise_error(AWS_ERROR_PLATFORM_NOT_SUPPORTED); +} + +size_t aws_ed25519_key_pair_get_private_key_size_impl(enum aws_ed25519_key_export_format format) { + (void)format; + AWS_FATAL_ASSERT(0); + return 0; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-cal-0.8.3/source/shared/lccrypto_common.c new/aws-c-cal-0.8.5/source/shared/lccrypto_common.c --- old/aws-c-cal-0.8.3/source/shared/lccrypto_common.c 1970-01-01 01:00:00.000000000 +0100 +++ new/aws-c-cal-0.8.5/source/shared/lccrypto_common.c 2025-03-05 01:40:09.000000000 +0100 @@ -0,0 +1,75 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/cal/cal.h> +#include <aws/cal/private/opensslcrypto_common.h> + +#define OPENSSL_SUPPRESS_DEPRECATED +#include <openssl/err.h> +#include <openssl/evp.h> + +#if defined(OPENSSL_IS_OPENSSL) +/*Error defines were part of evp.h in 1.0.x and were moved to evperr.h in 1.1.0*/ +# if OPENSSL_VERSION_NUMBER >= 0x10100000L +# include <openssl/evperr.h> +# endif +#else +# include <openssl/evp_errors.h> +#endif + +/* + * Transforms evp error code into crt error code and raises it as necessary. + * All evp functions follow the same: + * >= 1 for success + * <= 0 for failure + * -2 always indicates incorrect algo for operation + */ +int aws_reinterpret_lc_evp_error_as_crt(int evp_error, const char *function_name, enum aws_cal_log_subject subject) { + if (evp_error > 0) { + return AWS_OP_SUCCESS; + } + + /* AWS-LC/BoringSSL error code is uint32_t, but OpenSSL uses unsigned long. */ +#if defined(OPENSSL_IS_OPENSSL) + uint32_t error = ERR_peek_error(); +#else + unsigned long error = ERR_peek_error(); +#endif + + int crt_error = AWS_OP_ERR; + const char *error_message = ERR_reason_error_string(error); + + if (evp_error == -2) { + crt_error = AWS_ERROR_CAL_UNSUPPORTED_ALGORITHM; + goto on_error; + } + + if (ERR_GET_LIB(error) == ERR_LIB_EVP) { + switch (ERR_GET_REASON(error)) { + case EVP_R_BUFFER_TOO_SMALL: { + crt_error = AWS_ERROR_SHORT_BUFFER; + goto on_error; + } + case EVP_R_UNSUPPORTED_ALGORITHM: { + crt_error = AWS_ERROR_CAL_UNSUPPORTED_ALGORITHM; + goto on_error; + } + } + } + + crt_error = AWS_ERROR_CAL_CRYPTO_OPERATION_FAILED; + +on_error: + AWS_LOGF_ERROR( + subject, + "%s() failed. returned: %d extended error:%lu(%s) aws_error:%s", + function_name, + evp_error, + (unsigned long)error, + error_message == NULL ? "" : error_message, + aws_error_name(crt_error)); + + return aws_raise_error(crt_error); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-cal-0.8.3/source/unix/openssl_platform_init.c new/aws-c-cal-0.8.5/source/unix/openssl_platform_init.c --- old/aws-c-cal-0.8.3/source/unix/openssl_platform_init.c 2025-01-29 19:14:48.000000000 +0100 +++ new/aws-c-cal-0.8.5/source/unix/openssl_platform_init.c 2025-03-05 01:40:09.000000000 +0100 @@ -34,10 +34,6 @@ static struct aws_allocator *s_libcrypto_allocator = NULL; -#if !defined(OPENSSL_IS_AWSLC) && !defined(OPENSSL_IS_BORINGSSL) -# define OPENSSL_IS_OPENSSL -#endif - /* weak refs to libcrypto functions to force them to at least try to link * and avoid dead-stripping */ @@ -613,7 +609,7 @@ * will need to be addressed by increasing buffer size.*/ char expected_version[64] = {0}; #if defined(OPENSSL_IS_AWSLC) - /* get FIPS mode at runtime becuase headers don't give any indication of + /* get FIPS mode at runtime because headers don't give any indication of * AWS-LC's FIPSness at aws-c-cal compile time. version number can still be * captured at preprocess/compile time from AWSLC_VERSION_NUMBER_STRING.*/ const char *mode = FIPS_mode() ? "AWS-LC FIPS" : "AWS-LC"; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-cal-0.8.3/source/unix/openssl_rsa.c new/aws-c-cal-0.8.5/source/unix/openssl_rsa.c --- old/aws-c-cal-0.8.3/source/unix/openssl_rsa.c 2025-01-29 19:14:48.000000000 +0100 +++ new/aws-c-cal-0.8.5/source/unix/openssl_rsa.c 2025-03-05 01:40:09.000000000 +0100 @@ -9,18 +9,8 @@ #include <aws/common/encoding.h> #define OPENSSL_SUPPRESS_DEPRECATED -#include <openssl/err.h> #include <openssl/evp.h> -#if defined(OPENSSL_IS_OPENSSL) -/*Error defines were part of evp.h in 1.0.x and were moved to evperr.h in 1.1.0*/ -# if OPENSSL_VERSION_NUMBER >= 0x10100000L -# include <openssl/evperr.h> -# endif -#else -# include <openssl/evp_errors.h> -#endif - #include <openssl/rsa.h> struct lc_rsa_key_pair { @@ -45,76 +35,24 @@ aws_mem_release(base->allocator, impl); } -/* - * Transforms evp error code into crt error code and raises it as necessary. - * All evp functions follow the same: - * >= 1 for success - * <= 0 for failure - * -2 always indicates incorrect algo for operation - */ -static int s_reinterpret_evp_error_as_crt(int evp_error, const char *function_name) { - if (evp_error > 0) { - return AWS_OP_SUCCESS; - } - - /* AWS-LC/BoringSSL error code is uint32_t, but OpenSSL uses unsigned long. */ -#if defined(OPENSSL_IS_OPENSSL) - uint32_t error = ERR_peek_error(); -#else - unsigned long error = ERR_peek_error(); -#endif - - int crt_error = AWS_OP_ERR; - const char *error_message = ERR_reason_error_string(error); - - if (evp_error == -2) { - crt_error = AWS_ERROR_CAL_UNSUPPORTED_ALGORITHM; - goto on_error; - } - - if (ERR_GET_LIB(error) == ERR_LIB_EVP) { - switch (ERR_GET_REASON(error)) { - case EVP_R_BUFFER_TOO_SMALL: { - crt_error = AWS_ERROR_SHORT_BUFFER; - goto on_error; - } - case EVP_R_UNSUPPORTED_ALGORITHM: { - crt_error = AWS_ERROR_CAL_UNSUPPORTED_ALGORITHM; - goto on_error; - } - } - } - - crt_error = AWS_ERROR_CAL_CRYPTO_OPERATION_FAILED; - -on_error: - AWS_LOGF_ERROR( - AWS_LS_CAL_RSA, - "%s() failed. returned: %d extended error:%lu(%s) aws_error:%s", - function_name, - evp_error, - (unsigned long)error, - error_message == NULL ? "" : error_message, - aws_error_name(crt_error)); - - return aws_raise_error(crt_error); -} - static int s_set_encryption_ctx_from_algo(EVP_PKEY_CTX *ctx, enum aws_rsa_encryption_algorithm algorithm) { if (algorithm == AWS_CAL_RSA_ENCRYPTION_PKCS1_5) { - if (s_reinterpret_evp_error_as_crt( - EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING), "EVP_PKEY_CTX_set_rsa_padding")) { + if (aws_reinterpret_lc_evp_error_as_crt( + EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING), "EVP_PKEY_CTX_set_rsa_padding", AWS_LS_CAL_RSA)) { return AWS_OP_ERR; } } else if (algorithm == AWS_CAL_RSA_ENCRYPTION_OAEP_SHA256 || algorithm == AWS_CAL_RSA_ENCRYPTION_OAEP_SHA512) { - if (s_reinterpret_evp_error_as_crt( - EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING), "EVP_PKEY_CTX_set_rsa_padding")) { + if (aws_reinterpret_lc_evp_error_as_crt( + EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING), + "EVP_PKEY_CTX_set_rsa_padding", + AWS_LS_CAL_RSA)) { return AWS_OP_ERR; } const EVP_MD *md = algorithm == AWS_CAL_RSA_ENCRYPTION_OAEP_SHA256 ? EVP_sha256() : EVP_sha512(); - if (s_reinterpret_evp_error_as_crt(EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md), "EVP_PKEY_CTX_set_rsa_oaep_md")) { + if (aws_reinterpret_lc_evp_error_as_crt( + EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md), "EVP_PKEY_CTX_set_rsa_oaep_md", AWS_LS_CAL_RSA)) { return AWS_OP_ERR; } } else { @@ -136,7 +74,7 @@ return aws_raise_error(AWS_ERROR_CAL_CRYPTO_OPERATION_FAILED); } - if (s_reinterpret_evp_error_as_crt(EVP_PKEY_encrypt_init(ctx), "EVP_PKEY_encrypt_init")) { + if (aws_reinterpret_lc_evp_error_as_crt(EVP_PKEY_encrypt_init(ctx), "EVP_PKEY_encrypt_init", AWS_LS_CAL_RSA)) { goto on_error; } @@ -145,9 +83,10 @@ } size_t needed_buffer_len = 0; - if (s_reinterpret_evp_error_as_crt( + if (aws_reinterpret_lc_evp_error_as_crt( EVP_PKEY_encrypt(ctx, NULL, &needed_buffer_len, plaintext.ptr, plaintext.len), - "EVP_PKEY_encrypt get length")) { + "EVP_PKEY_encrypt get length", + AWS_LS_CAL_RSA)) { goto on_error; } @@ -165,8 +104,10 @@ goto on_error; } - if (s_reinterpret_evp_error_as_crt( - EVP_PKEY_encrypt(ctx, out->buffer + out->len, &ct_len, plaintext.ptr, plaintext.len), "EVP_PKEY_encrypt")) { + if (aws_reinterpret_lc_evp_error_as_crt( + EVP_PKEY_encrypt(ctx, out->buffer + out->len, &ct_len, plaintext.ptr, plaintext.len), + "EVP_PKEY_encrypt", + AWS_LS_CAL_RSA)) { goto on_error; } out->len += ct_len; @@ -191,7 +132,7 @@ return aws_raise_error(AWS_ERROR_CAL_CRYPTO_OPERATION_FAILED); } - if (s_reinterpret_evp_error_as_crt(EVP_PKEY_decrypt_init(ctx), "EVP_PKEY_decrypt_init")) { + if (aws_reinterpret_lc_evp_error_as_crt(EVP_PKEY_decrypt_init(ctx), "EVP_PKEY_decrypt_init", AWS_LS_CAL_RSA)) { goto on_error; } @@ -200,9 +141,10 @@ } size_t needed_buffer_len = 0; - if (s_reinterpret_evp_error_as_crt( + if (aws_reinterpret_lc_evp_error_as_crt( EVP_PKEY_decrypt(ctx, NULL, &needed_buffer_len, ciphertext.ptr, ciphertext.len), - "EVP_PKEY_decrypt get length")) { + "EVP_PKEY_decrypt get length", + AWS_LS_CAL_RSA)) { goto on_error; } @@ -216,9 +158,10 @@ goto on_error; } - if (s_reinterpret_evp_error_as_crt( + if (aws_reinterpret_lc_evp_error_as_crt( EVP_PKEY_decrypt(ctx, out->buffer + out->len, &ct_len, ciphertext.ptr, ciphertext.len), - "EVP_PKEY_decrypt")) { + "EVP_PKEY_decrypt", + AWS_LS_CAL_RSA)) { goto on_error; } out->len += ct_len; @@ -233,26 +176,28 @@ static int s_set_signature_ctx_from_algo(EVP_PKEY_CTX *ctx, enum aws_rsa_signature_algorithm algorithm) { if (algorithm == AWS_CAL_RSA_SIGNATURE_PKCS1_5_SHA256) { - if (s_reinterpret_evp_error_as_crt( - EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING), "EVP_PKEY_CTX_set_rsa_padding")) { + if (aws_reinterpret_lc_evp_error_as_crt( + EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING), "EVP_PKEY_CTX_set_rsa_padding", AWS_LS_CAL_RSA)) { return AWS_OP_ERR; } - if (s_reinterpret_evp_error_as_crt( - EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()), "EVP_PKEY_CTX_set_signature_md")) { + if (aws_reinterpret_lc_evp_error_as_crt( + EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()), "EVP_PKEY_CTX_set_signature_md", AWS_LS_CAL_RSA)) { return AWS_OP_ERR; } } else if (algorithm == AWS_CAL_RSA_SIGNATURE_PKCS1_5_SHA1) { - if (s_reinterpret_evp_error_as_crt( - EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING), "EVP_PKEY_CTX_set_rsa_padding")) { + if (aws_reinterpret_lc_evp_error_as_crt( + EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING), "EVP_PKEY_CTX_set_rsa_padding", AWS_LS_CAL_RSA)) { return AWS_OP_ERR; } - if (s_reinterpret_evp_error_as_crt( - EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha1()), "EVP_PKEY_CTX_set_signature_md")) { + if (aws_reinterpret_lc_evp_error_as_crt( + EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha1()), "EVP_PKEY_CTX_set_signature_md", AWS_LS_CAL_RSA)) { return AWS_OP_ERR; } } else if (algorithm == AWS_CAL_RSA_SIGNATURE_PSS_SHA256) { - if (s_reinterpret_evp_error_as_crt( - EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING), "EVP_PKEY_CTX_set_rsa_padding")) { + if (aws_reinterpret_lc_evp_error_as_crt( + EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING), + "EVP_PKEY_CTX_set_rsa_padding", + AWS_LS_CAL_RSA)) { return AWS_OP_ERR; } @@ -262,13 +207,13 @@ int saltlen = RSA_PSS_SALTLEN_DIGEST; #endif - if (s_reinterpret_evp_error_as_crt( - EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen), "EVP_PKEY_CTX_set_rsa_pss_saltlen")) { + if (aws_reinterpret_lc_evp_error_as_crt( + EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen), "EVP_PKEY_CTX_set_rsa_pss_saltlen", AWS_LS_CAL_RSA)) { return AWS_OP_ERR; } - if (s_reinterpret_evp_error_as_crt( - EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()), "EVP_PKEY_CTX_set_signature_md")) { + if (aws_reinterpret_lc_evp_error_as_crt( + EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()), "EVP_PKEY_CTX_set_signature_md", AWS_LS_CAL_RSA)) { return AWS_OP_ERR; } } else { @@ -290,7 +235,7 @@ return aws_raise_error(AWS_ERROR_CAL_CRYPTO_OPERATION_FAILED); } - if (s_reinterpret_evp_error_as_crt(EVP_PKEY_sign_init(ctx), "EVP_PKEY_sign_init")) { + if (aws_reinterpret_lc_evp_error_as_crt(EVP_PKEY_sign_init(ctx), "EVP_PKEY_sign_init", AWS_LS_CAL_RSA)) { goto on_error; } @@ -299,8 +244,10 @@ } size_t needed_buffer_len = 0; - if (s_reinterpret_evp_error_as_crt( - EVP_PKEY_sign(ctx, NULL, &needed_buffer_len, digest.ptr, digest.len), "EVP_PKEY_sign get length")) { + if (aws_reinterpret_lc_evp_error_as_crt( + EVP_PKEY_sign(ctx, NULL, &needed_buffer_len, digest.ptr, digest.len), + "EVP_PKEY_sign get length", + AWS_LS_CAL_RSA)) { goto on_error; } @@ -318,8 +265,10 @@ goto on_error; } - if (s_reinterpret_evp_error_as_crt( - EVP_PKEY_sign(ctx, out->buffer + out->len, &ct_len, digest.ptr, digest.len), "EVP_PKEY_sign")) { + if (aws_reinterpret_lc_evp_error_as_crt( + EVP_PKEY_sign(ctx, out->buffer + out->len, &ct_len, digest.ptr, digest.len), + "EVP_PKEY_sign", + AWS_LS_CAL_RSA)) { goto on_error; } out->len += ct_len; @@ -344,7 +293,7 @@ return aws_raise_error(AWS_ERROR_CAL_CRYPTO_OPERATION_FAILED); } - if (s_reinterpret_evp_error_as_crt(EVP_PKEY_verify_init(ctx), "EVP_PKEY_verify_init")) { + if (aws_reinterpret_lc_evp_error_as_crt(EVP_PKEY_verify_init(ctx), "EVP_PKEY_verify_init", AWS_LS_CAL_RSA)) { goto on_error; } @@ -362,7 +311,7 @@ } else if (error_code == 0) { return aws_raise_error(AWS_ERROR_CAL_SIGNATURE_VALIDATION_FAILED); } else { - return s_reinterpret_evp_error_as_crt(error_code, "EVP_PKEY_verify"); + return aws_reinterpret_lc_evp_error_as_crt(error_code, "EVP_PKEY_verify", AWS_LS_CAL_RSA); } on_error: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-cal-0.8.3/source/windows/bcrypt_platform_init.c new/aws-c-cal-0.8.5/source/windows/bcrypt_platform_init.c --- old/aws-c-cal-0.8.3/source/windows/bcrypt_platform_init.c 2025-01-29 19:14:48.000000000 +0100 +++ new/aws-c-cal-0.8.5/source/windows/bcrypt_platform_init.c 2025-03-05 01:40:09.000000000 +0100 @@ -4,11 +4,34 @@ */ #include <aws/common/allocator.h> +#if defined(AWS_USE_LIBCRYPTO_TO_SUPPORT_ED25519_EVERYWHERE) && defined(OPENSSL_IS_AWSLC) +# include <openssl/thread.h> +# include <windows.h> +#endif void aws_cal_platform_init(struct aws_allocator *allocator) { (void)allocator; } -void aws_cal_platform_clean_up(void) {} +void aws_cal_platform_clean_up(void) { +#if defined(AWS_USE_LIBCRYPTO_TO_SUPPORT_ED25519_EVERYWHERE) && defined(OPENSSL_IS_AWSLC) + AWSLC_thread_local_clear(); +#endif +} + +void aws_cal_platform_thread_clean_up(void) { +#if defined(AWS_USE_LIBCRYPTO_TO_SUPPORT_ED25519_EVERYWHERE) && defined(OPENSSL_IS_AWSLC) + AWSLC_thread_local_clear(); +#endif +} -void aws_cal_platform_thread_clean_up(void) {} +#if defined(AWS_USE_LIBCRYPTO_TO_SUPPORT_ED25519_EVERYWHERE) && defined(OPENSSL_IS_AWSLC) +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { + switch (fdwReason) { + case DLL_PROCESS_DETACH: + AWSLC_thread_local_shutdown(); + break; + } + return TRUE; +} +#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-cal-0.8.3/tests/CMakeLists.txt new/aws-c-cal-0.8.5/tests/CMakeLists.txt --- old/aws-c-cal-0.8.3/tests/CMakeLists.txt 2025-01-29 19:14:48.000000000 +0100 +++ new/aws-c-cal-0.8.5/tests/CMakeLists.txt 2025-03-05 01:40:09.000000000 +0100 @@ -154,4 +154,14 @@ add_test_case(ecc_key_pair_private_ref_count_test) add_test_case(ecc_key_gen_from_private_fuzz_test) +add_test_case(ed25519_key_pair_generate_test) + generate_test_driver(${PROJECT_NAME}-tests) + +# OpenBSD 7.4+ defaults to linking with --execute-only which is not always safe for AWS-LC. +# We have similar link flags in bindings, but in this case we need on the test executable, +# because ed25519 keygen is hitting the same issue +# (according to aws-lc huge tables in text section for ed25519 is the likely culprit) +if(CMAKE_SYSTEM_NAME MATCHES "OpenBSD") + target_link_options(${PROJECT_NAME}-tests PRIVATE "-Wl,--no-execute-only") +endif() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-cal-0.8.3/tests/ed25519_test.c new/aws-c-cal-0.8.5/tests/ed25519_test.c --- old/aws-c-cal-0.8.3/tests/ed25519_test.c 1970-01-01 01:00:00.000000000 +0100 +++ new/aws-c-cal-0.8.5/tests/ed25519_test.c 2025-03-05 01:40:09.000000000 +0100 @@ -0,0 +1,71 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +#include <aws/cal/ed25519.h> + +#include <aws/testing/aws_test_harness.h> + +#include "test_case_helper.h" + +static int s_ed25519_key_pair_generate_test(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + (void)allocator; + + aws_cal_library_test_init(allocator); + + struct aws_ed25519_key_pair *pair = aws_ed25519_key_pair_new_generate(allocator); + + AWS_LOGF_DEBUG(0, "%p", pair); + + if (pair == NULL && aws_last_error() == AWS_ERROR_PLATFORM_NOT_SUPPORTED) { +#if defined(AWS_USE_LIBCRYPTO_TO_SUPPORT_ED25519_EVERYWHERE) + ASSERT_TRUE(false); +#endif + return AWS_OP_SKIP; + } + + ASSERT_NOT_NULL(pair); + + struct aws_byte_buf buf_pub_ssh; + aws_byte_buf_init( + &buf_pub_ssh, allocator, aws_ed25519_key_pair_get_public_key_size(AWS_CAL_ED25519_KEY_EXPORT_OPENSSH_B64)); + + ASSERT_SUCCESS(aws_ed25519_key_pair_get_public_key(pair, AWS_CAL_ED25519_KEY_EXPORT_OPENSSH_B64, &buf_pub_ssh)); + ASSERT_UINT_EQUALS(buf_pub_ssh.len, 68); + + struct aws_byte_buf buf_pub_raw; + aws_byte_buf_init( + &buf_pub_raw, allocator, aws_ed25519_key_pair_get_public_key_size(AWS_CAL_ED25519_KEY_EXPORT_RAW)); + + ASSERT_SUCCESS(aws_ed25519_key_pair_get_public_key(pair, AWS_CAL_ED25519_KEY_EXPORT_RAW, &buf_pub_raw)); + ASSERT_UINT_EQUALS(buf_pub_raw.len, 32); + + struct aws_byte_buf buf_priv_ssh; + aws_byte_buf_init( + &buf_priv_ssh, allocator, aws_ed25519_key_pair_get_private_key_size(AWS_CAL_ED25519_KEY_EXPORT_OPENSSH_B64)); + + ASSERT_SUCCESS(aws_ed25519_key_pair_get_private_key(pair, AWS_CAL_ED25519_KEY_EXPORT_OPENSSH_B64, &buf_priv_ssh)); + ASSERT_UINT_EQUALS(buf_priv_ssh.len, 312); + + struct aws_byte_buf buf_priv_raw; + aws_byte_buf_init( + &buf_priv_raw, allocator, aws_ed25519_key_pair_get_private_key_size(AWS_CAL_ED25519_KEY_EXPORT_RAW)); + + ASSERT_SUCCESS(aws_ed25519_key_pair_get_private_key(pair, AWS_CAL_ED25519_KEY_EXPORT_RAW, &buf_priv_raw)); + ASSERT_UINT_EQUALS(buf_priv_raw.len, 32); + + ASSERT_NOT_NULL(pair); + aws_ed25519_key_pair_release(pair); + + aws_byte_buf_clean_up(&buf_pub_ssh); + aws_byte_buf_clean_up(&buf_priv_ssh); + aws_byte_buf_clean_up(&buf_pub_raw); + aws_byte_buf_clean_up(&buf_priv_raw); + + aws_cal_library_clean_up(); + + return AWS_OP_SUCCESS; +} + +AWS_TEST_CASE(ed25519_key_pair_generate_test, s_ed25519_key_pair_generate_test)