diff options
| author | arcadia-devtools <[email protected]> | 2022-05-11 16:05:18 +0300 |
|---|---|---|
| committer | arcadia-devtools <[email protected]> | 2022-05-11 16:05:18 +0300 |
| commit | 8081dabe0c602237a85fac90c08c050810c240c3 (patch) | |
| tree | e5dd432078beca69191590df6ea1c9414bcb8bb2 | |
| parent | 2fa85bfea497fb80ee8c522afaac5c7894cde1ff (diff) | |
intermediate changes
ref:7c9437ac8c8c891f086176fb334bd6177f7f93d7
14 files changed, 593 insertions, 216 deletions
diff --git a/contrib/restricted/aws/aws-c-cal/CONTRIBUTING.md b/contrib/restricted/aws/aws-c-cal/CONTRIBUTING.md index 2b96875d0a7..3fa822f96da 100644 --- a/contrib/restricted/aws/aws-c-cal/CONTRIBUTING.md +++ b/contrib/restricted/aws/aws-c-cal/CONTRIBUTING.md @@ -23,7 +23,7 @@ reported the issue. Please try to include as much information as you can. Detail ## Contributing via Pull Requests Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: -1. You are working against the latest source on the *master* branch. +1. You are working against the latest source on the *main* branch. 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. @@ -56,6 +56,6 @@ If you discover a potential security issue in this project we ask that you notif ## Licensing -See the [LICENSE](https://github.com/awslabs/aws-c-cal/blob/master/LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. +See the [LICENSE](https://github.com/awslabs/aws-c-cal/blob/main/LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes. diff --git a/contrib/restricted/aws/aws-c-cal/README.md b/contrib/restricted/aws/aws-c-cal/README.md index 78f2b8a9193..b50c8d4aa41 100644 --- a/contrib/restricted/aws/aws-c-cal/README.md +++ b/contrib/restricted/aws/aws-c-cal/README.md @@ -12,27 +12,32 @@ This library is licensed under the Apache 2.0 License. * Unix (via OpenSSL compatible libcrypto) ## Build Instructions -Since this project builds with CMake, you can build with whichever tool you prefer. Here, we show make for simplicity. You can -use Visual Studio, XCode, or whatever you'd like via the -G option. + +CMake 3.0+ is required to build. + +`<install-path>` must be an absolute path in the following instructions. + +#### Linux-Only Dependencies + +If you are building on Linux, you will need to build aws-lc first. ``` -git clone [email protected]:awslabs/aws-c-common -mkdir aws-c-common-build -cd aws-c-common-build -cmake -DCMAKE_PREFIX_PATH=<install path> -DCMAKE_INSTALL_PREFIX=<install path> ../aws-c-common -make -make test -make install - -cd .. -git clone [email protected]:awslabs/aws-c-cal -mkdir aws-c-cal-build -cd aws-c-cal-build -cmake -DCMAKE_PREFIX_PATH=<install path> -DCMAKE_INSTALL_PREFIX=<install path> ../aws-c-cal -make -make test -make install -```` +git clone [email protected]:awslabs/aws-lc.git +cmake -S aws-lc -B aws-lc/build -DCMAKE_INSTALL_PREFIX=<install-path> +cmake --build aws-lc/build --target install +``` + +#### Building aws-c-cal and Remaining Dependencies + +``` +git clone [email protected]:awslabs/aws-c-common.git +cmake -S aws-c-common -B aws-c-common/build -DCMAKE_INSTALL_PREFIX=<install-path> +cmake --build aws-c-common/build --target install + +git clone [email protected]:awslabs/aws-c-cal.git +cmake -S aws-c-cal -B aws-c-cal/build -DCMAKE_INSTALL_PREFIX=<install-path> -DCMAKE_PREFIX_PATH=<install-path> +cmake --build aws-c-cal/build --target install +``` ## Currently provided algorithms diff --git a/contrib/restricted/aws/aws-c-cal/include/aws/cal/cal.h b/contrib/restricted/aws/aws-c-cal/include/aws/cal/cal.h index 8c6986842be..5456c91900d 100644 --- a/contrib/restricted/aws/aws-c-cal/include/aws/cal/cal.h +++ b/contrib/restricted/aws/aws-c-cal/include/aws/cal/cal.h @@ -6,6 +6,7 @@ */ #include <aws/common/common.h> +#include <aws/common/logging.h> #include <aws/cal/exports.h> @@ -25,6 +26,17 @@ enum aws_cal_errors { AWS_ERROR_CAL_END_RANGE = AWS_ERROR_ENUM_END_RANGE(AWS_C_CAL_PACKAGE_ID) }; +enum aws_cal_log_subject { + AWS_LS_CAL_GENERAL = AWS_LOG_SUBJECT_BEGIN_RANGE(AWS_C_CAL_PACKAGE_ID), + AWS_LS_CAL_ECC, + AWS_LS_CAL_HASH, + AWS_LS_CAL_HMAC, + AWS_LS_CAL_DER, + AWS_LS_CAL_LIBCRYPTO_RESOLVE, + + AWS_LS_CAL_LAST = AWS_LOG_SUBJECT_END_RANGE(AWS_C_CAL_PACKAGE_ID) +}; + AWS_EXTERN_C_BEGIN AWS_CAL_API void aws_cal_library_init(struct aws_allocator *allocator); diff --git a/contrib/restricted/aws/aws-c-cal/include/aws/cal/hash.h b/contrib/restricted/aws/aws-c-cal/include/aws/cal/hash.h index ebf70e39e4a..16be7210442 100644 --- a/contrib/restricted/aws/aws-c-cal/include/aws/cal/hash.h +++ b/contrib/restricted/aws/aws-c-cal/include/aws/cal/hash.h @@ -10,6 +10,7 @@ #include <aws/common/common.h> #define AWS_SHA256_LEN 32 +#define AWS_SHA1_LEN 20 #define AWS_MD5_LEN 16 struct aws_hash; @@ -38,9 +39,14 @@ AWS_EXTERN_C_BEGIN */ AWS_CAL_API struct aws_hash *aws_sha256_new(struct aws_allocator *allocator); /** + * Allocates and initializes a sha1 hash instance. + */ +AWS_CAL_API struct aws_hash *aws_sha1_new(struct aws_allocator *allocator); +/** * Allocates and initializes an md5 hash instance. */ AWS_CAL_API struct aws_hash *aws_md5_new(struct aws_allocator *allocator); + /** * Cleans up and deallocates hash. */ @@ -53,7 +59,7 @@ AWS_CAL_API int aws_hash_update(struct aws_hash *hash, const struct aws_byte_cur * Completes the hash computation and writes the final digest to output. * Allocation of output is the caller's responsibility. If you specify * truncate_to to something other than 0, the output will be truncated to that - * number of bytes. For example if you want a SHA256 digest as the first 16 + * number of bytes. For example, if you want a SHA256 digest as the first 16 * bytes, set truncate_to to 16. If you want the full digest size, just set this * to 0. */ @@ -74,8 +80,8 @@ AWS_CAL_API int aws_md5_compute( * Computes the sha256 hash over input and writes the digest output to 'output'. * Use this if you don't need to stream the data you're hashing and you can load * the entire input to hash into memory. If you specify truncate_to to something - * other than 0, the output will be truncated to that number of bytes. For - * example if you want a SHA256 digest as the first 16 bytes, set truncate_to + * other than 0, the output will be truncated to that number of bytes. For + * example, if you want a SHA256 digest as the first 16 bytes, set truncate_to * to 16. If you want the full digest size, just set this to 0. */ AWS_CAL_API int aws_sha256_compute( @@ -85,23 +91,46 @@ AWS_CAL_API int aws_sha256_compute( size_t truncate_to); /** - * Set the implementation of md5 to use. If you compiled without AWS_BYO_CRYPTO, + * Computes the sha1 hash over input and writes the digest output to 'output'. + * Use this if you don't need to stream the data you're hashing and you can load + * the entire input to hash into memory. If you specify truncate_to to something + * other than 0, the output will be truncated to that number of bytes. For + * example, if you want a SHA1 digest as the first 16 bytes, set truncate_to + * to 16. If you want the full digest size, just set this to 0. + */ +AWS_CAL_API int aws_sha1_compute( + struct aws_allocator *allocator, + const struct aws_byte_cursor *input, + struct aws_byte_buf *output, + size_t truncate_to); + +/** + * Set the implementation of md5 to use. If you compiled without BYO_CRYPTO, * you do not need to call this. However, if use this, we will honor it, * regardless of compile options. This may be useful for testing purposes. If - * you did set AWS_BYO_CRYPTO, and you do not call this function you will + * you did set BYO_CRYPTO, and you do not call this function you will * segfault. */ AWS_CAL_API void aws_set_md5_new_fn(aws_hash_new_fn *fn); /** * Set the implementation of sha256 to use. If you compiled without - * AWS_BYO_CRYPTO, you do not need to call this. However, if use this, we will + * BYO_CRYPTO, you do not need to call this. However, if use this, we will * honor it, regardless of compile options. This may be useful for testing - * purposes. If you did set AWS_BYO_CRYPTO, and you do not call this function + * purposes. If you did set BYO_CRYPTO, and you do not call this function * you will segfault. */ AWS_CAL_API void aws_set_sha256_new_fn(aws_hash_new_fn *fn); +/** + * Set the implementation of sha1 to use. If you compiled without + * BYO_CRYPTO, you do not need to call this. However, if use this, we will + * honor it, regardless of compile options. This may be useful for testing + * purposes. If you did set BYO_CRYPTO, and you do not call this function + * you will segfault. + */ +AWS_CAL_API void aws_set_sha1_new_fn(aws_hash_new_fn *fn); + AWS_EXTERN_C_END #endif /* AWS_CAL_HASH_H_ */ diff --git a/contrib/restricted/aws/aws-c-cal/include/aws/cal/hmac.h b/contrib/restricted/aws/aws-c-cal/include/aws/cal/hmac.h index 42183887d67..6caf5cd7852 100644 --- a/contrib/restricted/aws/aws-c-cal/include/aws/cal/hmac.h +++ b/contrib/restricted/aws/aws-c-cal/include/aws/cal/hmac.h @@ -72,9 +72,9 @@ AWS_CAL_API int aws_sha256_hmac_compute( size_t truncate_to); /** * Set the implementation of sha256 hmac to use. If you compiled without - * AWS_BYO_CRYPTO, you do not need to call this. However, if use this, we will + * BYO_CRYPTO, you do not need to call this. However, if use this, we will * honor it, regardless of compile options. This may be useful for testing - * purposes. If you did set AWS_BYO_CRYPTO, and you do not call this function + * purposes. If you did set BYO_CRYPTO, and you do not call this function * you will segfault. */ AWS_CAL_API void aws_set_sha256_hmac_new_fn(aws_hmac_new_fn *fn); diff --git a/contrib/restricted/aws/aws-c-cal/include/aws/cal/private/opensslcrypto_common.h b/contrib/restricted/aws/aws-c-cal/include/aws/cal/private/opensslcrypto_common.h index f4e25c5f35f..1c80b9d5133 100644 --- a/contrib/restricted/aws/aws-c-cal/include/aws/cal/private/opensslcrypto_common.h +++ b/contrib/restricted/aws/aws-c-cal/include/aws/cal/private/opensslcrypto_common.h @@ -6,10 +6,10 @@ #include <openssl/hmac.h> typedef HMAC_CTX *(*hmac_ctx_new)(void); -typedef int (*hmac_ctx_reset)(HMAC_CTX *); +typedef void (*hmac_ctx_reset)(HMAC_CTX *); typedef void (*hmac_ctx_free)(HMAC_CTX *); typedef void (*hmac_ctx_init)(HMAC_CTX *); -typedef int (*hmac_ctx_init_ex)(HMAC_CTX *, const void *, int, const EVP_MD *, ENGINE *); +typedef int (*hmac_ctx_init_ex)(HMAC_CTX *, const void *, size_t, const EVP_MD *, ENGINE *); typedef void (*hmac_ctx_clean_up)(HMAC_CTX *); typedef int (*hmac_ctx_update)(HMAC_CTX *, const unsigned char *, size_t); typedef int (*hmac_ctx_final)(HMAC_CTX *, unsigned char *, unsigned int *); diff --git a/contrib/restricted/aws/aws-c-cal/source/cal.c b/contrib/restricted/aws/aws-c-cal/source/cal.c index d0792ce09a3..e793035cb4c 100644 --- a/contrib/restricted/aws/aws-c-cal/source/cal.c +++ b/contrib/restricted/aws/aws-c-cal/source/cal.c @@ -40,8 +40,30 @@ static struct aws_error_info_list s_list = { .count = AWS_ARRAY_SIZE(s_errors), }; +static struct aws_log_subject_info s_cal_log_subject_infos[] = { + DEFINE_LOG_SUBJECT_INFO( + AWS_LS_CAL_GENERAL, + "aws-c-cal", + "Subject for Cal logging that doesn't belong to any particular category"), + DEFINE_LOG_SUBJECT_INFO(AWS_LS_CAL_ECC, "ecc", "Subject for elliptic curve cryptography specific logging."), + DEFINE_LOG_SUBJECT_INFO(AWS_LS_CAL_HASH, "hash", "Subject for hashing specific logging."), + DEFINE_LOG_SUBJECT_INFO(AWS_LS_CAL_HMAC, "hmac", "Subject for hmac specific logging."), + DEFINE_LOG_SUBJECT_INFO(AWS_LS_CAL_DER, "der", "Subject for der specific logging."), + DEFINE_LOG_SUBJECT_INFO( + AWS_LS_CAL_LIBCRYPTO_RESOLVE, + "libcrypto_resolve", + "Subject for libcrypto symbol resolution logging."), +}; + +static struct aws_log_subject_info_list s_cal_log_subject_list = { + .subject_list = s_cal_log_subject_infos, + .count = AWS_ARRAY_SIZE(s_cal_log_subject_infos), +}; + +#ifndef BYO_CRYPTO extern void aws_cal_platform_init(struct aws_allocator *allocator); extern void aws_cal_platform_clean_up(void); +#endif /* BYO_CRYPTO */ static bool s_cal_library_initialized = false; @@ -49,14 +71,20 @@ void aws_cal_library_init(struct aws_allocator *allocator) { if (!s_cal_library_initialized) { aws_common_library_init(allocator); aws_register_error_info(&s_list); + aws_register_log_subject_info_list(&s_cal_log_subject_list); +#ifndef BYO_CRYPTO aws_cal_platform_init(allocator); +#endif /* BYO_CRYPTO */ s_cal_library_initialized = true; } } void aws_cal_library_clean_up(void) { if (s_cal_library_initialized) { s_cal_library_initialized = false; +#ifndef BYO_CRYPTO aws_cal_platform_clean_up(); +#endif /* BYO_CRYPTO */ + aws_unregister_log_subject_info_list(&s_cal_log_subject_list); aws_unregister_error_info(&s_list); aws_common_library_clean_up(); } diff --git a/contrib/restricted/aws/aws-c-cal/source/ecc.c b/contrib/restricted/aws/aws-c-cal/source/ecc.c index d4e65fda643..ca944e07f28 100644 --- a/contrib/restricted/aws/aws-c-cal/source/ecc.c +++ b/contrib/restricted/aws/aws-c-cal/source/ecc.c @@ -62,6 +62,77 @@ int aws_ecc_oid_from_curve_name(enum aws_ecc_curve_name curve_name, struct aws_b return AWS_OP_SUCCESS; } +typedef struct aws_ecc_key_pair *(aws_ecc_key_pair_new_from_public_key_fn)( + struct aws_allocator *allocator, + enum aws_ecc_curve_name curve_name, + const struct aws_byte_cursor *public_key_x, + const struct aws_byte_cursor *public_key_y); + +typedef struct aws_ecc_key_pair *(aws_ecc_key_pair_new_from_private_key_fn)( + struct aws_allocator *allocator, + enum aws_ecc_curve_name curve_name, + const struct aws_byte_cursor *priv_key); + +#ifndef BYO_CRYPTO + +extern struct aws_ecc_key_pair *aws_ecc_key_pair_new_from_public_key_impl( + struct aws_allocator *allocator, + enum aws_ecc_curve_name curve_name, + const struct aws_byte_cursor *public_key_x, + const struct aws_byte_cursor *public_key_y); + +extern struct aws_ecc_key_pair *aws_ecc_key_pair_new_from_private_key_impl( + struct aws_allocator *allocator, + enum aws_ecc_curve_name curve_name, + const struct aws_byte_cursor *priv_key); + +#else /* BYO_CRYPTO */ + +struct aws_ecc_key_pair *aws_ecc_key_pair_new_from_public_key_impl( + struct aws_allocator *allocator, + enum aws_ecc_curve_name curve_name, + const struct aws_byte_cursor *public_key_x, + const struct aws_byte_cursor *public_key_y) { + (void)allocator; + (void)curve_name; + (void)public_key_x; + (void)public_key_y; + abort(); +} + +struct aws_ecc_key_pair *aws_ecc_key_pair_new_from_private_key_impl( + struct aws_allocator *allocator, + enum aws_ecc_curve_name curve_name, + const struct aws_byte_cursor *priv_key) { + (void)allocator; + (void)curve_name; + (void)priv_key; + abort(); +} + +#endif /* BYO_CRYPTO */ + +static aws_ecc_key_pair_new_from_public_key_fn *s_ecc_key_pair_new_from_public_key_fn = + aws_ecc_key_pair_new_from_public_key_impl; + +static aws_ecc_key_pair_new_from_private_key_fn *s_ecc_key_pair_new_from_private_key_fn = + aws_ecc_key_pair_new_from_private_key_impl; + +struct aws_ecc_key_pair *aws_ecc_key_pair_new_from_public_key( + struct aws_allocator *allocator, + enum aws_ecc_curve_name curve_name, + const struct aws_byte_cursor *public_key_x, + const struct aws_byte_cursor *public_key_y) { + return s_ecc_key_pair_new_from_public_key_fn(allocator, curve_name, public_key_x, public_key_y); +} + +struct aws_ecc_key_pair *aws_ecc_key_pair_new_from_private_key( + struct aws_allocator *allocator, + enum aws_ecc_curve_name curve_name, + const struct aws_byte_cursor *priv_key) { + return s_ecc_key_pair_new_from_private_key_fn(allocator, curve_name, priv_key); +} + static void s_aws_ecc_key_pair_destroy(struct aws_ecc_key_pair *key_pair) { if (key_pair) { AWS_FATAL_ASSERT(key_pair->vtable->destroy && "ECC KEY PAIR destroy function must be included on the vtable"); diff --git a/contrib/restricted/aws/aws-c-cal/source/hash.c b/contrib/restricted/aws/aws-c-cal/source/hash.c index 9a797cf1a5d..37891277323 100644 --- a/contrib/restricted/aws/aws-c-cal/source/hash.c +++ b/contrib/restricted/aws/aws-c-cal/source/hash.c @@ -4,11 +4,13 @@ */ #include <aws/cal/hash.h> -#ifndef AWS_BYO_CRYPTO +#ifndef BYO_CRYPTO extern struct aws_hash *aws_sha256_default_new(struct aws_allocator *allocator); +extern struct aws_hash *aws_sha1_default_new(struct aws_allocator *allocator); extern struct aws_hash *aws_md5_default_new(struct aws_allocator *allocator); static aws_hash_new_fn *s_sha256_new_fn = aws_sha256_default_new; +static aws_hash_new_fn *s_sha1_new_fn = aws_sha1_default_new; static aws_hash_new_fn *s_md5_new_fn = aws_md5_default_new; #else static struct aws_hash *aws_hash_new_abort(struct aws_allocator *allocator) { @@ -17,9 +19,14 @@ static struct aws_hash *aws_hash_new_abort(struct aws_allocator *allocator) { } static aws_hash_new_fn *s_sha256_new_fn = aws_hash_new_abort; +static aws_hash_new_fn *s_sha1_new_fn = aws_hash_new_abort; static aws_hash_new_fn *s_md5_new_fn = aws_hash_new_abort; #endif +struct aws_hash *aws_sha1_new(struct aws_allocator *allocator) { + return s_sha1_new_fn(allocator); +} + struct aws_hash *aws_sha256_new(struct aws_allocator *allocator) { return s_sha256_new_fn(allocator); } @@ -36,6 +43,10 @@ void aws_set_sha256_new_fn(aws_hash_new_fn *fn) { s_sha256_new_fn = fn; } +void aws_set_sha1_new_fn(aws_hash_new_fn *fn) { + s_sha1_new_fn = fn; +} + void aws_hash_destroy(struct aws_hash *hash) { hash->vtable->destroy(hash); } @@ -108,3 +119,11 @@ int aws_sha256_compute( size_t truncate_to) { return compute_hash(aws_sha256_new(allocator), input, output, truncate_to); } + +int aws_sha1_compute( + struct aws_allocator *allocator, + const struct aws_byte_cursor *input, + struct aws_byte_buf *output, + size_t truncate_to) { + return compute_hash(aws_sha1_new(allocator), input, output, truncate_to); +} diff --git a/contrib/restricted/aws/aws-c-cal/source/hmac.c b/contrib/restricted/aws/aws-c-cal/source/hmac.c index 01f5ea58980..e5042145e0f 100644 --- a/contrib/restricted/aws/aws-c-cal/source/hmac.c +++ b/contrib/restricted/aws/aws-c-cal/source/hmac.c @@ -4,7 +4,7 @@ */ #include <aws/cal/hmac.h> -#ifndef AWS_BYO_CRYPTO +#ifndef BYO_CRYPTO extern struct aws_hmac *aws_sha256_hmac_default_new( struct aws_allocator *allocator, const struct aws_byte_cursor *secret); diff --git a/contrib/restricted/aws/aws-c-cal/source/unix/openssl_platform_init.c b/contrib/restricted/aws/aws-c-cal/source/unix/openssl_platform_init.c index 761455b8216..c9e44e5b85e 100644 --- a/contrib/restricted/aws/aws-c-cal/source/unix/openssl_platform_init.c +++ b/contrib/restricted/aws/aws-c-cal/source/unix/openssl_platform_init.c @@ -3,7 +3,9 @@ * SPDX-License-Identifier: Apache-2.0. */ +#include <aws/cal/cal.h> #include <aws/common/allocator.h> +#include <aws/common/logging.h> #include <aws/common/mutex.h> #include <aws/common/thread.h> @@ -11,40 +13,40 @@ #include <aws/cal/private/opensslcrypto_common.h> -#if defined(AWS_LIBCRYPTO_LOG_RESOLVE) -# define FLOGF(...) \ - do { \ - fprintf(stderr, "AWS libcrypto resolve: "); \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n"); \ - } while (0) -#else -# define FLOGF(...) -#endif - static struct openssl_hmac_ctx_table hmac_ctx_table; static struct openssl_evp_md_ctx_table evp_md_ctx_table; struct openssl_hmac_ctx_table *g_aws_openssl_hmac_ctx_table = NULL; struct openssl_evp_md_ctx_table *g_aws_openssl_evp_md_ctx_table = NULL; +static struct aws_allocator *s_libcrypto_allocator = NULL; + /* weak refs to libcrypto functions to force them to at least try to link * and avoid dead-stripping */ +#if defined(OPENSSL_IS_AWSLC) +extern HMAC_CTX *HMAC_CTX_new(void) __attribute__((weak, used)); +extern void HMAC_CTX_free(HMAC_CTX *) __attribute__((weak, used)); +extern void HMAC_CTX_reset(HMAC_CTX *) __attribute__((weak, used)); +extern void HMAC_CTX_init(HMAC_CTX *) __attribute__((weak, used)); +extern void HMAC_CTX_cleanup(HMAC_CTX *) __attribute__((weak, used)); +extern int HMAC_Update(HMAC_CTX *, const unsigned char *, size_t) __attribute__((weak, used)); +extern int HMAC_Final(HMAC_CTX *, unsigned char *, unsigned int *) __attribute__((weak, used)); +extern int HMAC_Init_ex(HMAC_CTX *, const void *, size_t, const EVP_MD *, ENGINE *) __attribute__((weak, used)); +#else /* 1.1 */ -extern HMAC_CTX *HMAC_CTX_new(void) __attribute__((weak)) __attribute__((used)); -extern void HMAC_CTX_free(HMAC_CTX *) __attribute__((weak)) __attribute__((used)); -extern int HMAC_CTX_reset(HMAC_CTX *) __attribute__((weak)) __attribute__((used)); +extern HMAC_CTX *HMAC_CTX_new(void) __attribute__((weak, used)); +extern void HMAC_CTX_free(HMAC_CTX *) __attribute__((weak, used)); +extern int HMAC_CTX_reset(HMAC_CTX *) __attribute__((weak, used)); /* 1.0.2 */ -extern void HMAC_CTX_init(HMAC_CTX *) __attribute__((weak)) __attribute__((used)); -extern void HMAC_CTX_cleanup(HMAC_CTX *) __attribute__((weak)) __attribute__((used)); +extern void HMAC_CTX_init(HMAC_CTX *) __attribute__((weak, used)); +extern void HMAC_CTX_cleanup(HMAC_CTX *) __attribute__((weak, used)); /* common */ -extern int HMAC_Update(HMAC_CTX *, const unsigned char *, size_t) __attribute__((weak)) __attribute__((used)); -extern int HMAC_Final(HMAC_CTX *, unsigned char *, unsigned int *) __attribute__((weak)) __attribute__((used)); -extern int HMAC_Init_ex(HMAC_CTX *, const void *, int, const EVP_MD *, ENGINE *) __attribute__((weak)) -__attribute__((used)); +extern int HMAC_Update(HMAC_CTX *, const unsigned char *, size_t) __attribute__((weak, used)); +extern int HMAC_Final(HMAC_CTX *, unsigned char *, unsigned int *) __attribute__((weak, used)); +extern int HMAC_Init_ex(HMAC_CTX *, const void *, int, const EVP_MD *, ENGINE *) __attribute__((weak, used)); /* libcrypto 1.1 stub for init */ static void s_hmac_ctx_init_noop(HMAC_CTX *ctx) { @@ -61,7 +63,7 @@ static HMAC_CTX *s_hmac_ctx_new(void) { AWS_PRECONDITION( g_aws_openssl_hmac_ctx_table->init_fn != s_hmac_ctx_init_noop && "libcrypto 1.0 init called on libcrypto 1.1 vtable"); - HMAC_CTX *ctx = aws_mem_calloc(aws_default_allocator(), 1, 300); + HMAC_CTX *ctx = aws_mem_calloc(s_libcrypto_allocator, 1, 300); AWS_FATAL_ASSERT(ctx && "Unable to allocate to HMAC_CTX"); g_aws_openssl_hmac_ctx_table->init_fn(ctx); return ctx; @@ -74,7 +76,7 @@ static void s_hmac_ctx_free(HMAC_CTX *ctx) { g_aws_openssl_hmac_ctx_table->clean_up_fn != s_hmac_ctx_clean_up_noop && "libcrypto 1.0 clean_up called on libcrypto 1.1 vtable"); g_aws_openssl_hmac_ctx_table->clean_up_fn(ctx); - aws_mem_release(aws_default_allocator(), ctx); + aws_mem_release(s_libcrypto_allocator, ctx); } /* libcrypto 1.0 shim for reset, matches HMAC_CTX_reset semantics */ @@ -89,23 +91,7 @@ static int s_hmac_ctx_reset(HMAC_CTX *ctx) { return 1; } -static struct aws_mutex *s_libcrypto_locks = NULL; -static struct aws_allocator *s_libcrypto_allocator = NULL; - -static void s_locking_fn(int mode, int n, const char *unused0, int unused1) { - (void)unused0; - (void)unused1; - - if (mode & CRYPTO_LOCK) { - aws_mutex_lock(&s_libcrypto_locks[n]); - } else { - aws_mutex_unlock(&s_libcrypto_locks[n]); - } -} - -static unsigned long s_id_fn(void) { - return (unsigned long)aws_thread_current_thread_id(); -} +#endif /* !OPENSSL_IS_AWSLC */ enum aws_libcrypto_version { AWS_LIBCRYPTO_NONE = 0, @@ -114,55 +100,61 @@ enum aws_libcrypto_version { AWS_LIBCRYPTO_LC, } s_libcrypto_version = AWS_LIBCRYPTO_NONE; -static int s_resolve_libcrypto_hmac(enum aws_libcrypto_version version, void *module) { - hmac_ctx_init init_fn = HMAC_CTX_init; - hmac_ctx_clean_up clean_up_fn = HMAC_CTX_cleanup; - hmac_ctx_new new_fn = HMAC_CTX_new; - hmac_ctx_free free_fn = HMAC_CTX_free; - hmac_ctx_reset reset_fn = HMAC_CTX_reset; - hmac_ctx_update update_fn = HMAC_Update; - hmac_ctx_final final_fn = HMAC_Final; - hmac_ctx_init_ex init_ex_fn = HMAC_Init_ex; +bool s_resolve_hmac_102(void *module) { +#if !defined(OPENSSL_IS_AWSLC) + hmac_ctx_init init_fn = (hmac_ctx_init)HMAC_CTX_init; + hmac_ctx_clean_up clean_up_fn = (hmac_ctx_clean_up)HMAC_CTX_cleanup; + hmac_ctx_update update_fn = (hmac_ctx_update)HMAC_Update; + hmac_ctx_final final_fn = (hmac_ctx_final)HMAC_Final; + hmac_ctx_init_ex init_ex_fn = (hmac_ctx_init_ex)HMAC_Init_ex; /* were symbols bound by static linking? */ bool has_102_symbols = init_fn && clean_up_fn && update_fn && final_fn && init_ex_fn; - bool has_111_symbols = new_fn && free_fn && update_fn && final_fn && init_ex_fn && reset_fn; - - if (version == AWS_LIBCRYPTO_NONE) { - if (has_102_symbols) { - version = AWS_LIBCRYPTO_1_0_2; - FLOGF("auto-resolving libcrypto 1.0.2"); - } else if (has_111_symbols) { - version = AWS_LIBCRYPTO_1_1_1; - FLOGF("auto-resolving libcrypto 1.1.1"); - } else { - /* not pre-linked, need to ask for a specific version */ - return AWS_LIBCRYPTO_NONE; - } - } - if (has_102_symbols) { - FLOGF("found static libcrypto 1.0.2 HMAC"); - } - if (has_111_symbols) { - FLOGF("found static libcrypto 1.1.1 HMAC"); - } - - /* If symbols aren't already found, try to find the requested version */ - /* when built as a shared lib, and multiple versions of openssl are possibly - * available (e.g. brazil), select 1.0.2 by default for consistency */ - if (!has_102_symbols && version == AWS_LIBCRYPTO_1_0_2) { + AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "found static libcrypto 1.0.2 HMAC symbols"); + } else { + /* If symbols aren't already found, try to find the requested version */ *(void **)(&init_fn) = dlsym(module, "HMAC_CTX_init"); *(void **)(&clean_up_fn) = dlsym(module, "HMAC_CTX_cleanup"); *(void **)(&update_fn) = dlsym(module, "HMAC_Update"); *(void **)(&final_fn) = dlsym(module, "HMAC_Final"); *(void **)(&init_ex_fn) = dlsym(module, "HMAC_Init_ex"); if (init_fn) { - FLOGF("found dynamic libcrypto 1.0.2 HMAC symbols"); + AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "found dynamic libcrypto 1.0.2 HMAC symbols"); } } - if (!has_111_symbols && version == AWS_LIBCRYPTO_1_1_1) { + if (init_fn) { + hmac_ctx_table.new_fn = (hmac_ctx_new)s_hmac_ctx_new; + hmac_ctx_table.reset_fn = (hmac_ctx_reset)s_hmac_ctx_reset; + hmac_ctx_table.free_fn = s_hmac_ctx_free; + hmac_ctx_table.init_fn = init_fn; + hmac_ctx_table.clean_up_fn = clean_up_fn; + hmac_ctx_table.update_fn = update_fn; + hmac_ctx_table.final_fn = final_fn; + hmac_ctx_table.init_ex_fn = init_ex_fn; + g_aws_openssl_hmac_ctx_table = &hmac_ctx_table; + return true; + } +#endif + return false; +} + +bool s_resolve_hmac_111(void *module) { +#if !defined(OPENSSL_IS_AWSLC) + hmac_ctx_new new_fn = (hmac_ctx_new)HMAC_CTX_new; + hmac_ctx_free free_fn = (hmac_ctx_free)HMAC_CTX_free; + hmac_ctx_reset reset_fn = (hmac_ctx_reset)HMAC_CTX_reset; + hmac_ctx_update update_fn = (hmac_ctx_update)HMAC_Update; + hmac_ctx_final final_fn = (hmac_ctx_final)HMAC_Final; + hmac_ctx_init_ex init_ex_fn = (hmac_ctx_init_ex)HMAC_Init_ex; + + /* were symbols bound by static linking? */ + bool has_111_symbols = new_fn && free_fn && update_fn && final_fn && init_ex_fn && reset_fn; + + if (has_111_symbols) { + AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "found static libcrypto 1.1.1 HMAC symbols"); + } else { *(void **)(&new_fn) = dlsym(module, "HMAC_CTX_new"); *(void **)(&reset_fn) = dlsym(module, "HMAC_CTX_reset"); *(void **)(&free_fn) = dlsym(module, "HMAC_CTX_free"); @@ -170,214 +162,387 @@ static int s_resolve_libcrypto_hmac(enum aws_libcrypto_version version, void *mo *(void **)(&final_fn) = dlsym(module, "HMAC_Final"); *(void **)(&init_ex_fn) = dlsym(module, "HMAC_Init_ex"); if (new_fn) { - FLOGF("found dynamic libcrypto 1.1.1 HMAC symbols"); + AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "found dynamic libcrypto 1.1.1 HMAC symbols"); } } - /* Fill out the vtable for the requested version */ - if (version == AWS_LIBCRYPTO_1_0_2 && init_fn) { - hmac_ctx_table.new_fn = s_hmac_ctx_new; - hmac_ctx_table.reset_fn = s_hmac_ctx_reset; - hmac_ctx_table.free_fn = s_hmac_ctx_free; - hmac_ctx_table.init_fn = init_fn; - hmac_ctx_table.clean_up_fn = clean_up_fn; - } else if (version == AWS_LIBCRYPTO_1_1_1 && new_fn) { + if (new_fn) { hmac_ctx_table.new_fn = new_fn; hmac_ctx_table.reset_fn = reset_fn; hmac_ctx_table.free_fn = free_fn; hmac_ctx_table.init_fn = s_hmac_ctx_init_noop; hmac_ctx_table.clean_up_fn = s_hmac_ctx_clean_up_noop; + hmac_ctx_table.update_fn = update_fn; + hmac_ctx_table.final_fn = final_fn; + hmac_ctx_table.init_ex_fn = init_ex_fn; + g_aws_openssl_hmac_ctx_table = &hmac_ctx_table; + return true; + } +#endif + return false; +} + +bool s_resolve_hmac_lc(void *module) { +#if defined(OPENSSL_IS_AWSLC) + hmac_ctx_init init_fn = (hmac_ctx_init)HMAC_CTX_init; + hmac_ctx_clean_up clean_up_fn = (hmac_ctx_clean_up)HMAC_CTX_cleanup; + hmac_ctx_new new_fn = (hmac_ctx_new)HMAC_CTX_new; + hmac_ctx_free free_fn = (hmac_ctx_free)HMAC_CTX_free; + hmac_ctx_reset reset_fn = (hmac_ctx_reset)HMAC_CTX_reset; + hmac_ctx_update update_fn = (hmac_ctx_update)HMAC_Update; + hmac_ctx_final final_fn = (hmac_ctx_final)HMAC_Final; + hmac_ctx_init_ex init_ex_fn = (hmac_ctx_init_ex)HMAC_Init_ex; + + /* were symbols bound by static linking? */ + bool has_awslc_symbols = new_fn && free_fn && update_fn && final_fn && init_fn && init_ex_fn && reset_fn; + + /* If symbols aren't already found, try to find the requested version */ + /* when built as a shared lib, and multiple versions of libcrypto are possibly + * available (e.g. brazil), select AWS-LC by default for consistency */ + if (has_awslc_symbols) { + AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "found static aws-lc HMAC symbols"); + } else { + *(void **)(&new_fn) = dlsym(module, "HMAC_CTX_new"); + *(void **)(&reset_fn) = dlsym(module, "HMAC_CTX_reset"); + *(void **)(&free_fn) = dlsym(module, "HMAC_CTX_free"); + *(void **)(&update_fn) = dlsym(module, "HMAC_Update"); + *(void **)(&final_fn) = dlsym(module, "HMAC_Final"); + *(void **)(&init_ex_fn) = dlsym(module, "HMAC_Init_ex"); + if (new_fn) { + AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "found dynamic aws-lc HMAC symbols"); + } + } + + if (new_fn) { + /* Fill out the vtable for the requested version */ + hmac_ctx_table.new_fn = new_fn; + hmac_ctx_table.reset_fn = reset_fn; + hmac_ctx_table.free_fn = free_fn; + hmac_ctx_table.init_fn = init_fn; + hmac_ctx_table.clean_up_fn = clean_up_fn; + hmac_ctx_table.update_fn = update_fn; + hmac_ctx_table.final_fn = final_fn; + hmac_ctx_table.init_ex_fn = init_ex_fn; + g_aws_openssl_hmac_ctx_table = &hmac_ctx_table; + return true; + } +#endif + return false; +} + +static enum aws_libcrypto_version s_resolve_libcrypto_hmac(enum aws_libcrypto_version version, void *module) { + switch (version) { + case AWS_LIBCRYPTO_LC: + return s_resolve_hmac_lc(module) ? version : AWS_LIBCRYPTO_NONE; + case AWS_LIBCRYPTO_1_1_1: + return s_resolve_hmac_111(module) ? version : AWS_LIBCRYPTO_NONE; + case AWS_LIBCRYPTO_1_0_2: + return s_resolve_hmac_102(module) ? version : AWS_LIBCRYPTO_NONE; + case AWS_LIBCRYPTO_NONE: + AWS_FATAL_ASSERT(!"Attempted to resolve invalid libcrypto HMAC API version AWS_LIBCRYPTO_NONE"); } - hmac_ctx_table.update_fn = update_fn; - hmac_ctx_table.final_fn = final_fn; - hmac_ctx_table.init_ex_fn = init_ex_fn; - g_aws_openssl_hmac_ctx_table = &hmac_ctx_table; - return version; + return AWS_LIBCRYPTO_NONE; } +#if !defined(OPENSSL_IS_AWSLC) /* EVP_MD_CTX API */ /* 1.0.2 NOTE: these are macros in 1.1.x, so we have to undef them to weak link */ -#if defined(EVP_MD_CTX_create) -# pragma push_macro("EVP_MD_CTX_create") -# undef EVP_MD_CTX_create -#endif +# if defined(EVP_MD_CTX_create) +# pragma push_macro("EVP_MD_CTX_create") +# undef EVP_MD_CTX_create +# endif extern EVP_MD_CTX *EVP_MD_CTX_create(void) __attribute__((weak, used)); static evp_md_ctx_new s_EVP_MD_CTX_create = EVP_MD_CTX_create; -#if defined(EVP_MD_CTX_create) -# pragma pop_macro("EVP_MD_CTX_create") -#endif - -#if defined(EVP_MD_CTX_destroy) -# pragma push_macro("EVP_MD_CTX_destroy") -# undef EVP_MD_CTX_destroy -#endif +# if defined(EVP_MD_CTX_create) +# pragma pop_macro("EVP_MD_CTX_create") +# endif + +# if defined(EVP_MD_CTX_destroy) +# pragma push_macro("EVP_MD_CTX_destroy") +# undef EVP_MD_CTX_destroy +# endif extern void EVP_MD_CTX_destroy(EVP_MD_CTX *) __attribute__((weak, used)); static evp_md_ctx_free s_EVP_MD_CTX_destroy = EVP_MD_CTX_destroy; -#if defined(EVP_MD_CTX_destroy) -# pragma pop_macro("EVP_MD_CTX_destroy") -#endif +# if defined(EVP_MD_CTX_destroy) +# pragma pop_macro("EVP_MD_CTX_destroy") +# endif +#endif /* !OPENSSL_IS_AWSLC */ -/* 1.1 */ extern EVP_MD_CTX *EVP_MD_CTX_new(void) __attribute__((weak, used)); extern void EVP_MD_CTX_free(EVP_MD_CTX *) __attribute__((weak, used)); - -/* common */ extern int EVP_DigestInit_ex(EVP_MD_CTX *, const EVP_MD *, ENGINE *) __attribute__((weak, used)); extern int EVP_DigestUpdate(EVP_MD_CTX *, const void *, size_t) __attribute__((weak, used)); extern int EVP_DigestFinal_ex(EVP_MD_CTX *, unsigned char *, unsigned int *) __attribute__((weak, used)); -static int s_resolve_libcrypto_md(enum aws_libcrypto_version version, void *module) { - /* OpenSSL changed the EVP api in 1.1 to use new/free verbs */ - evp_md_ctx_new md_new_fn = EVP_MD_CTX_new; +bool s_resolve_md_102(void *module) { +#if !defined(OPENSSL_IS_AWSLC) evp_md_ctx_new md_create_fn = s_EVP_MD_CTX_create; - evp_md_ctx_free md_free_fn = EVP_MD_CTX_free; evp_md_ctx_free md_destroy_fn = s_EVP_MD_CTX_destroy; evp_md_ctx_digest_init_ex md_init_ex_fn = EVP_DigestInit_ex; evp_md_ctx_digest_update md_update_fn = EVP_DigestUpdate; evp_md_ctx_digest_final_ex md_final_ex_fn = EVP_DigestFinal_ex; bool has_102_symbols = md_create_fn && md_destroy_fn && md_init_ex_fn && md_update_fn && md_final_ex_fn; - bool has_111_symbols = md_new_fn && md_free_fn && md_init_ex_fn && md_update_fn && md_final_ex_fn; if (has_102_symbols) { - FLOGF("found static libcrypto 1.0.2 EVP_MD"); - } - if (has_111_symbols) { - FLOGF("found static libcrypto 1.1.1 EVP_MD"); - } - - if (!has_102_symbols && version == AWS_LIBCRYPTO_1_0_2) { + AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "found static libcrypto 1.0.2 EVP_MD symbols"); + } else { *(void **)(&md_create_fn) = dlsym(module, "EVP_MD_CTX_create"); *(void **)(&md_destroy_fn) = dlsym(module, "EVP_MD_CTX_destroy"); *(void **)(&md_init_ex_fn) = dlsym(module, "EVP_DigestInit_ex"); *(void **)(&md_update_fn) = dlsym(module, "EVP_DigestUpdate"); *(void **)(&md_final_ex_fn) = dlsym(module, "EVP_DigestFinal_ex"); if (md_create_fn) { - FLOGF("found dynamic libcrypto 1.0.2 EVP_MD symbols"); + AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "found dynamic libcrypto 1.0.2 EVP_MD symbols"); } } - if (!has_111_symbols && version == AWS_LIBCRYPTO_1_1_1) { + if (md_create_fn) { + evp_md_ctx_table.new_fn = md_create_fn; + evp_md_ctx_table.free_fn = md_destroy_fn; + evp_md_ctx_table.init_ex_fn = md_init_ex_fn; + evp_md_ctx_table.update_fn = md_update_fn; + evp_md_ctx_table.final_ex_fn = md_final_ex_fn; + g_aws_openssl_evp_md_ctx_table = &evp_md_ctx_table; + return true; + } +#endif + return false; +} + +bool s_resolve_md_111(void *module) { +#if !defined(OPENSSL_IS_AWSLC) + evp_md_ctx_new md_new_fn = EVP_MD_CTX_new; + evp_md_ctx_free md_free_fn = EVP_MD_CTX_free; + evp_md_ctx_digest_init_ex md_init_ex_fn = EVP_DigestInit_ex; + evp_md_ctx_digest_update md_update_fn = EVP_DigestUpdate; + evp_md_ctx_digest_final_ex md_final_ex_fn = EVP_DigestFinal_ex; + + bool has_111_symbols = md_new_fn && md_free_fn && md_init_ex_fn && md_update_fn && md_final_ex_fn; + if (has_111_symbols) { + AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "found static libcrypto 1.1.1 EVP_MD symbols"); + } else { *(void **)(&md_new_fn) = dlsym(module, "EVP_MD_CTX_new"); *(void **)(&md_free_fn) = dlsym(module, "EVP_MD_CTX_free"); *(void **)(&md_init_ex_fn) = dlsym(module, "EVP_DigestInit_ex"); *(void **)(&md_update_fn) = dlsym(module, "EVP_DigestUpdate"); *(void **)(&md_final_ex_fn) = dlsym(module, "EVP_DigestFinal_ex"); if (md_new_fn) { - FLOGF("found dynamic libcrypto 1.1.1 EVP_MD symbols"); + AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "found dynamic libcrypto 1.1.1 EVP_MD symbols"); } } - /* Add the found symbols to the vtable */ - if (version == AWS_LIBCRYPTO_1_0_2 && md_create_fn) { - evp_md_ctx_table.new_fn = md_create_fn; - evp_md_ctx_table.free_fn = md_destroy_fn; + if (md_new_fn) { + evp_md_ctx_table.new_fn = md_new_fn; + evp_md_ctx_table.free_fn = md_free_fn; evp_md_ctx_table.init_ex_fn = md_init_ex_fn; evp_md_ctx_table.update_fn = md_update_fn; evp_md_ctx_table.final_ex_fn = md_final_ex_fn; g_aws_openssl_evp_md_ctx_table = &evp_md_ctx_table; - return version; - } else if (version == AWS_LIBCRYPTO_1_1_1 && md_new_fn) { + return true; + } +#endif + return false; +} + +bool s_resolve_md_lc(void *module) { +#if defined(OPENSSL_IS_AWSLC) + evp_md_ctx_new md_new_fn = EVP_MD_CTX_new; + evp_md_ctx_new md_create_fn = EVP_MD_CTX_new; + evp_md_ctx_free md_free_fn = EVP_MD_CTX_free; + evp_md_ctx_free md_destroy_fn = EVP_MD_CTX_destroy; + evp_md_ctx_digest_init_ex md_init_ex_fn = EVP_DigestInit_ex; + evp_md_ctx_digest_update md_update_fn = EVP_DigestUpdate; + evp_md_ctx_digest_final_ex md_final_ex_fn = EVP_DigestFinal_ex; + + bool has_awslc_symbols = + md_new_fn && md_create_fn && md_free_fn && md_destroy_fn && md_init_ex_fn && md_update_fn && md_final_ex_fn; + + if (has_awslc_symbols) { + AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "found static aws-lc libcrypto 1.1.1 EVP_MD symbols"); + } else { + *(void **)(&md_new_fn) = dlsym(module, "EVP_MD_CTX_new"); + *(void **)(&md_free_fn) = dlsym(module, "EVP_MD_CTX_free"); + *(void **)(&md_init_ex_fn) = dlsym(module, "EVP_DigestInit_ex"); + *(void **)(&md_update_fn) = dlsym(module, "EVP_DigestUpdate"); + *(void **)(&md_final_ex_fn) = dlsym(module, "EVP_DigestFinal_ex"); + if (md_new_fn) { + AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "found dynamic aws-lc libcrypto 1.1.1 EVP_MD symbols"); + } + } + + if (md_new_fn) { + /* Add the found symbols to the vtable */ evp_md_ctx_table.new_fn = md_new_fn; evp_md_ctx_table.free_fn = md_free_fn; evp_md_ctx_table.init_ex_fn = md_init_ex_fn; evp_md_ctx_table.update_fn = md_update_fn; evp_md_ctx_table.final_ex_fn = md_final_ex_fn; g_aws_openssl_evp_md_ctx_table = &evp_md_ctx_table; - return version; + return true; + } +#endif + return false; +} + +static enum aws_libcrypto_version s_resolve_libcrypto_md(enum aws_libcrypto_version version, void *module) { + switch (version) { + case AWS_LIBCRYPTO_LC: + return s_resolve_md_lc(module) ? version : AWS_LIBCRYPTO_NONE; + case AWS_LIBCRYPTO_1_1_1: + return s_resolve_md_111(module) ? version : AWS_LIBCRYPTO_NONE; + case AWS_LIBCRYPTO_1_0_2: + return s_resolve_md_102(module) ? version : AWS_LIBCRYPTO_NONE; + case AWS_LIBCRYPTO_NONE: + AWS_FATAL_ASSERT(!"Attempted to resolve invalid libcrypto MD API version AWS_LIBCRYPTO_NONE"); } return AWS_LIBCRYPTO_NONE; } -static int s_resolve_libcrypto_symbols(enum aws_libcrypto_version version, void *module) { - int found_version = s_resolve_libcrypto_hmac(version, module); - if (!found_version) { +static enum aws_libcrypto_version s_resolve_libcrypto_symbols(enum aws_libcrypto_version version, void *module) { + enum aws_libcrypto_version found_version = s_resolve_libcrypto_hmac(version, module); + if (found_version == AWS_LIBCRYPTO_NONE) { return AWS_LIBCRYPTO_NONE; } - if (!s_resolve_libcrypto_md(found_version, module)) { + found_version = s_resolve_libcrypto_md(found_version, module); + if (found_version == AWS_LIBCRYPTO_NONE) { return AWS_LIBCRYPTO_NONE; } return found_version; } -static int s_resolve_libcrypto_version(enum aws_libcrypto_version version) { +static enum aws_libcrypto_version s_resolve_libcrypto_lib(void) { const char *libcrypto_102 = "libcrypto.so.1.0.0"; const char *libcrypto_111 = "libcrypto.so.1.1"; - switch (version) { - case AWS_LIBCRYPTO_NONE: { - FLOGF("searching process and loaded modules"); - void *process = dlopen(NULL, RTLD_NOW); - AWS_FATAL_ASSERT(process && "Unable to load symbols from process space"); - int result = s_resolve_libcrypto_symbols(version, process); - dlclose(process); + + AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "loading libcrypto 1.0.2"); + void *module = dlopen(libcrypto_102, RTLD_NOW); + if (module) { + AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "resolving against libcrypto 1.0.2"); + enum aws_libcrypto_version result = s_resolve_libcrypto_symbols(AWS_LIBCRYPTO_1_0_2, module); + if (result == AWS_LIBCRYPTO_1_0_2) { return result; } - case AWS_LIBCRYPTO_1_0_2: { - FLOGF("loading libcrypto 1.0.2"); - void *module = dlopen(libcrypto_102, RTLD_NOW); - if (module) { - FLOGF("resolving against libcrypto 1.0.2"); - int result = s_resolve_libcrypto_symbols(version, module); - dlclose(module); - return result; - } - FLOGF("libcrypto 1.0.2 not found"); - break; + dlclose(module); + } else { + AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "libcrypto 1.0.2 not found"); + } + + AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "loading libcrypto 1.1.1"); + module = dlopen(libcrypto_111, RTLD_NOW); + if (module) { + AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "resolving against libcrypto 1.1.1"); + enum aws_libcrypto_version result = s_resolve_libcrypto_symbols(AWS_LIBCRYPTO_1_1_1, module); + if (result == AWS_LIBCRYPTO_1_1_1) { + return result; } - case AWS_LIBCRYPTO_1_1_1: { - FLOGF("loading libcrypto 1.1.1"); - void *module = dlopen(libcrypto_111, RTLD_NOW); - if (module) { - FLOGF("resolving against libcrypto 1.1.1"); - int result = s_resolve_libcrypto_symbols(version, module); - dlclose(module); + dlclose(module); + } else { + AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "libcrypto 1.1.1 not found"); + } + + AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "loading libcrypto.so"); + module = dlopen("libcrypto.so", RTLD_NOW); + if (module) { + unsigned long (*openssl_version_num)(void) = NULL; + *(void **)(&openssl_version_num) = dlsym(module, "OpenSSL_version_num"); + if (openssl_version_num) { + unsigned long version = openssl_version_num(); + AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "libcrypto.so reported version is 0x%lx", version); + enum aws_libcrypto_version result = AWS_LIBCRYPTO_NONE; + if (version >= 0x10101000L) { + AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "probing libcrypto.so for 1.1.1 symbols"); + result = s_resolve_libcrypto_symbols(AWS_LIBCRYPTO_1_1_1, module); + } else if (version >= 0x10002000L) { + AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "probing libcrypto.so for 1.0.2 symbols"); + result = s_resolve_libcrypto_symbols(AWS_LIBCRYPTO_1_0_2, module); + } else { + AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "libcrypto.so reported version is unsupported"); + } + if (result != AWS_LIBCRYPTO_NONE) { return result; } - FLOGF("libcrypto 1.1.1 not found"); - break; + } else { + AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "Unable to determine version of libcrypto.so"); } - default: - AWS_FATAL_ASSERT("Attempted to use an unsupported version of libcrypto"); + dlclose(module); + } else { + AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "libcrypto.so not found"); } + return AWS_LIBCRYPTO_NONE; } -static int s_resolve_libcrypto(void) { +static void *s_libcrypto_module = NULL; + +static enum aws_libcrypto_version s_resolve_libcrypto(void) { if (s_libcrypto_version != AWS_LIBCRYPTO_NONE) { return s_libcrypto_version; } /* Try to auto-resolve against what's linked in/process space */ - FLOGF("Attempting auto-resolve against static linkage"); - s_libcrypto_version = s_resolve_libcrypto_version(AWS_LIBCRYPTO_NONE); - /* try 1.0.2 */ - if (s_libcrypto_version == AWS_LIBCRYPTO_NONE) { - FLOGF("Attempting resolve against libcrypto 1.0.2"); - s_libcrypto_version = s_resolve_libcrypto_version(AWS_LIBCRYPTO_1_0_2); + AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "searching process and loaded modules"); + void *process = dlopen(NULL, RTLD_NOW); + AWS_FATAL_ASSERT(process && "Unable to load symbols from process space"); + enum aws_libcrypto_version result = s_resolve_libcrypto_symbols(AWS_LIBCRYPTO_LC, process); + if (result == AWS_LIBCRYPTO_NONE) { + AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "did not find aws-lc symbols linked"); + result = s_resolve_libcrypto_symbols(AWS_LIBCRYPTO_1_0_2, process); } - /* try 1.1.1 */ - if (s_libcrypto_version == AWS_LIBCRYPTO_NONE) { - FLOGF("Attempting resolve against libcrypto 1.1.1"); - s_libcrypto_version = s_resolve_libcrypto_version(AWS_LIBCRYPTO_1_1_1); + if (result == AWS_LIBCRYPTO_NONE) { + AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "did not find libcrypto 1.0.2 symbols linked"); + result = s_resolve_libcrypto_symbols(AWS_LIBCRYPTO_1_1_1, process); + } + dlclose(process); + + if (result == AWS_LIBCRYPTO_NONE) { + AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "did not find libcrypto 1.1.1 symbols linked"); + AWS_LOGF_DEBUG( + AWS_LS_CAL_LIBCRYPTO_RESOLVE, + "libcrypto symbols were not statically linked, searching for shared libraries"); + result = s_resolve_libcrypto_lib(); } - return s_libcrypto_version; + return result; } /* Ignore warnings about how CRYPTO_get_locking_callback() always returns NULL on 1.1.1 */ -#if !defined(__GNUC__) || (__GNUC__ >= 4 && __GNUC_MINOR__ > 1) +#if !defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ * 10 > 410) # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Waddress" #endif -void aws_cal_platform_init(struct aws_allocator *allocator) { - s_libcrypto_allocator = allocator; +/* Openssl 1.0.x requires special handling for its locking callbacks or else it's not thread safe */ +#if !defined(OPENSSL_IS_AWSLC) +static struct aws_mutex *s_libcrypto_locks = NULL; +static void s_locking_fn(int mode, int n, const char *unused0, int unused1) { + (void)unused0; + (void)unused1; + + if (mode & CRYPTO_LOCK) { + aws_mutex_lock(&s_libcrypto_locks[n]); + } else { + aws_mutex_unlock(&s_libcrypto_locks[n]); + } +} + +static unsigned long s_id_fn(void) { + return (unsigned long)aws_thread_current_thread_id(); +} +#endif + +void aws_cal_platform_init(struct aws_allocator *allocator) { int version = s_resolve_libcrypto(); AWS_FATAL_ASSERT(version != AWS_LIBCRYPTO_NONE && "libcrypto could not be resolved"); + AWS_FATAL_ASSERT(g_aws_openssl_evp_md_ctx_table); + AWS_FATAL_ASSERT(g_aws_openssl_hmac_ctx_table); + + s_libcrypto_allocator = allocator; +#if !defined(OPENSSL_IS_AWSLC) /* Ensure that libcrypto 1.0.2 has working locking mechanisms. This code is macro'ed * by libcrypto to be a no-op on 1.1.1 */ if (!CRYPTO_get_locking_callback()) { @@ -396,9 +561,11 @@ void aws_cal_platform_init(struct aws_allocator *allocator) { if (!CRYPTO_get_id_callback()) { CRYPTO_set_id_callback(s_id_fn); } +#endif } void aws_cal_platform_clean_up(void) { +#if !defined(OPENSSL_IS_AWSLC) if (CRYPTO_get_locking_callback() == s_locking_fn) { CRYPTO_set_locking_callback(NULL); size_t lock_count = (size_t)CRYPTO_num_locks(); @@ -411,6 +578,13 @@ void aws_cal_platform_clean_up(void) { if (CRYPTO_get_id_callback() == s_id_fn) { CRYPTO_set_id_callback(NULL); } +#endif + + if (s_libcrypto_module) { + dlclose(s_libcrypto_module); + } + + s_libcrypto_allocator = NULL; } #if !defined(__GNUC__) || (__GNUC__ >= 4 && __GNUC_MINOR__ > 1) # pragma GCC diagnostic pop diff --git a/contrib/restricted/aws/aws-c-cal/source/unix/opensslcrypto_ecc.c b/contrib/restricted/aws/aws-c-cal/source/unix/opensslcrypto_ecc.c index 14be8c3df55..931d705bd29 100644 --- a/contrib/restricted/aws/aws-c-cal/source/unix/opensslcrypto_ecc.c +++ b/contrib/restricted/aws/aws-c-cal/source/unix/opensslcrypto_ecc.c @@ -156,13 +156,14 @@ static struct aws_ecc_key_pair_vtable vtable = { .destroy = s_key_pair_destroy, }; -struct aws_ecc_key_pair *aws_ecc_key_pair_new_from_private_key( +struct aws_ecc_key_pair *aws_ecc_key_pair_new_from_private_key_impl( struct aws_allocator *allocator, enum aws_ecc_curve_name curve_name, const struct aws_byte_cursor *priv_key) { size_t key_length = aws_ecc_key_coordinate_byte_size_from_curve_name(curve_name); if (priv_key->len != key_length) { + AWS_LOGF_ERROR(AWS_LS_CAL_ECC, "Private key length does not match curve's expected length"); aws_raise_error(AWS_ERROR_CAL_INVALID_KEY_LENGTH_FOR_ALGORITHM); return NULL; } @@ -179,6 +180,7 @@ struct aws_ecc_key_pair *aws_ecc_key_pair_new_from_private_key( BIGNUM *priv_key_num = BN_bin2bn(key_impl->key_pair.priv_d.buffer, key_impl->key_pair.priv_d.len, NULL); if (!EC_KEY_set_private_key(key_impl->ec_key, priv_key_num)) { + AWS_LOGF_ERROR(AWS_LS_CAL_ECC, "Failed to set openssl private key"); aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); BN_free(priv_key_num); s_key_pair_destroy(&key_impl->key_pair); @@ -225,7 +227,7 @@ error: return NULL; } -struct aws_ecc_key_pair *aws_ecc_key_pair_new_from_public_key( +struct aws_ecc_key_pair *aws_ecc_key_pair_new_from_public_key_impl( struct aws_allocator *allocator, enum aws_ecc_curve_name curve_name, const struct aws_byte_cursor *public_key_x, diff --git a/contrib/restricted/aws/aws-c-cal/source/unix/opensslcrypto_hash.c b/contrib/restricted/aws/aws-c-cal/source/unix/opensslcrypto_hash.c index e74237eec48..7ad284d0cce 100644 --- a/contrib/restricted/aws/aws-c-cal/source/unix/opensslcrypto_hash.c +++ b/contrib/restricted/aws/aws-c-cal/source/unix/opensslcrypto_hash.c @@ -28,6 +28,14 @@ static struct aws_hash_vtable s_sha256_vtable = { .provider = "OpenSSL Compatible libcrypto", }; +static struct aws_hash_vtable s_sha1_vtable = { + .destroy = s_destroy, + .update = s_update, + .finalize = s_finalize, + .alg_name = "SHA1", + .provider = "OpenSSL Compatible libcrypto", +}; + static void s_destroy(struct aws_hash *hash) { if (hash == NULL) { return; @@ -99,6 +107,35 @@ struct aws_hash *aws_sha256_default_new(struct aws_allocator *allocator) { return hash; } +struct aws_hash *aws_sha1_default_new(struct aws_allocator *allocator) { + struct aws_hash *hash = aws_mem_acquire(allocator, sizeof(struct aws_hash)); + + if (!hash) { + return NULL; + } + + hash->allocator = allocator; + hash->vtable = &s_sha1_vtable; + hash->digest_size = AWS_SHA1_LEN; + EVP_MD_CTX *ctx = g_aws_openssl_evp_md_ctx_table->new_fn(); + hash->impl = ctx; + hash->good = true; + + if (!hash->impl) { + s_destroy(hash); + aws_raise_error(AWS_ERROR_OOM); + return NULL; + } + + if (!g_aws_openssl_evp_md_ctx_table->init_ex_fn(ctx, EVP_sha1(), NULL)) { + s_destroy(hash); + aws_raise_error(AWS_ERROR_UNKNOWN); + return NULL; + } + + return hash; +} + static int s_update(struct aws_hash *hash, const struct aws_byte_cursor *to_hash) { if (!hash->good) { return aws_raise_error(AWS_ERROR_INVALID_STATE); @@ -129,7 +166,7 @@ static int s_finalize(struct aws_hash *hash, struct aws_byte_buf *output) { if (AWS_LIKELY(g_aws_openssl_evp_md_ctx_table->final_ex_fn( ctx, output->buffer + output->len, (unsigned int *)&buffer_len))) { - output->len += buffer_len; + output->len += hash->digest_size; hash->good = false; return AWS_OP_SUCCESS; } diff --git a/contrib/restricted/aws/aws-c-cal/source/unix/opensslcrypto_hmac.c b/contrib/restricted/aws/aws-c-cal/source/unix/opensslcrypto_hmac.c index b040ffdf5cd..5c5cc3686c7 100644 --- a/contrib/restricted/aws/aws-c-cal/source/unix/opensslcrypto_hmac.c +++ b/contrib/restricted/aws/aws-c-cal/source/unix/opensslcrypto_hmac.c @@ -113,7 +113,7 @@ static int s_finalize(struct aws_hmac *hmac, struct aws_byte_buf *output) { if (AWS_LIKELY( g_aws_openssl_hmac_ctx_table->final_fn(ctx, output->buffer + output->len, (unsigned int *)&buffer_len))) { hmac->good = false; - output->len += buffer_len; + output->len += hmac->digest_size; return AWS_OP_SUCCESS; } |
