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 2024-05-16 17:13:52 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/aws-c-cal (Old) and /work/SRC/openSUSE:Factory/.aws-c-cal.new.1880 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "aws-c-cal" Thu May 16 17:13:52 2024 rev:4 rq:1173652 version:0.6.13 Changes: -------- --- /work/SRC/openSUSE:Factory/aws-c-cal/aws-c-cal.changes 2024-04-16 20:11:24.365126249 +0200 +++ /work/SRC/openSUSE:Factory/.aws-c-cal.new.1880/aws-c-cal.changes 2024-05-16 17:15:46.613230439 +0200 @@ -1,0 +2,13 @@ +Mon May 13 09:14:06 UTC 2024 - John Paul Adrian Glaubitz <adrian.glaub...@suse.com> + +- Update to version 0.6.13 + * Fix handling of empty plaintext for AES by @DmitriyMusatkin in (#183) + * Adds a way to keep a more detailed state of a symetric cipher + by @sbiscigl in (#184) +- from version 0.6.12 + * CI test: Apple: explicitly include & link to CoreFoundation + by @jmklix in (#181) + * Move aws-lc shutdown to destructor from cleanup + by @DmitriyMusatkin in (#182) + +------------------------------------------------------------------- Old: ---- v0.6.11.tar.gz New: ---- v0.6.13.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ aws-c-cal.spec ++++++ --- /var/tmp/diff_new_pack.RJ7KtO/_old 2024-05-16 17:15:48.405295390 +0200 +++ /var/tmp/diff_new_pack.RJ7KtO/_new 2024-05-16 17:15:48.405295390 +0200 @@ -19,7 +19,7 @@ %define library_version 1.0.0 %define library_soversion 0unstable Name: aws-c-cal -Version: 0.6.11 +Version: 0.6.13 Release: 0 Summary: AWS C99 wrapper for cryptography primitives License: Apache-2.0 ++++++ v0.6.11.tar.gz -> v0.6.13.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-cal-0.6.11/CMakeLists.txt new/aws-c-cal-0.6.13/CMakeLists.txt --- old/aws-c-cal-0.6.11/CMakeLists.txt 2024-03-05 01:49:59.000000000 +0100 +++ new/aws-c-cal-0.6.13/CMakeLists.txt 2024-05-08 22:22:59.000000000 +0200 @@ -80,7 +80,13 @@ message(FATAL_ERROR "Security Framework not found") endif () - list(APPEND PLATFORM_LIBS "-framework Security") + + find_library(COREFOUNDATION_LIB CoreFoundation) + if(NOT COREFOUNDATION_LIB) + message(FATAL_ERROR "CoreFoundation Framework not found") + endif() + + list(APPEND PLATFORM_LIBS "-framework Security -framework CoreFoundation") endif() else () if (NOT BYO_CRYPTO) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-cal-0.6.11/include/aws/cal/private/symmetric_cipher_priv.h new/aws-c-cal-0.6.13/include/aws/cal/private/symmetric_cipher_priv.h --- old/aws-c-cal-0.6.11/include/aws/cal/private/symmetric_cipher_priv.h 2024-03-05 01:49:59.000000000 +0100 +++ new/aws-c-cal-0.6.13/include/aws/cal/private/symmetric_cipher_priv.h 2024-05-08 22:22:59.000000000 +0200 @@ -31,7 +31,16 @@ struct aws_byte_buf tag; size_t block_size; size_t key_length_bits; + /** + deprecated for use, only for backwards compat. + Use state to represent current state of cipher. + good represented if the ciphter was initialized + without any errors, ready to process input, + and not finialized yet. This corresponds to + the state AWS_SYMMETRIC_CIPHER_READY. + */ bool good; + enum aws_symmetric_cipher_state state; void *impl; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-cal-0.6.11/include/aws/cal/symmetric_cipher.h new/aws-c-cal-0.6.13/include/aws/cal/symmetric_cipher.h --- old/aws-c-cal-0.6.11/include/aws/cal/symmetric_cipher.h 2024-03-05 01:49:59.000000000 +0100 +++ new/aws-c-cal-0.6.13/include/aws/cal/symmetric_cipher.h 2024-05-08 22:22:59.000000000 +0200 @@ -35,6 +35,12 @@ typedef struct aws_symmetric_cipher *( aws_aes_keywrap_256_new_fn)(struct aws_allocator *allocator, const struct aws_byte_cursor *key); +enum aws_symmetric_cipher_state { + AWS_SYMMETRIC_CIPHER_READY, + AWS_SYMMETRIC_CIPHER_FINALIZED, + AWS_SYMMETRIC_CIPHER_ERROR, +}; + AWS_EXTERN_C_BEGIN /** @@ -239,4 +245,9 @@ AWS_EXTERN_C_END AWS_POP_SANE_WARNING_LEVEL +/** + * Retuns the current state of the cipher. Ther state of the cipher can be ready for use, finalized, or has encountered + * an error. if the cipher is in a finished or eror state, it must be reset before further use. + */ +AWS_CAL_API enum aws_symmetric_cipher_state aws_symmetric_cipher_get_state(const struct aws_symmetric_cipher *cipher); #endif /* AWS_CAL_SYMMETRIC_CIPHER_H */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-cal-0.6.11/source/darwin/commoncrypto_aes.c new/aws-c-cal-0.6.13/source/darwin/commoncrypto_aes.c --- old/aws-c-cal-0.6.11/source/darwin/commoncrypto_aes.c 2024-03-05 01:49:59.000000000 +0100 +++ new/aws-c-cal-0.6.13/source/darwin/commoncrypto_aes.c 2024-05-08 22:22:59.000000000 +0200 @@ -46,7 +46,7 @@ cc_cipher->encryptor_handle, input.ptr, input.len, out->buffer + out->len, available_write_space, &len_written); if (status != kCCSuccess) { - cipher->good = false; + cipher->state = AWS_SYMMETRIC_CIPHER_ERROR; return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); } @@ -70,7 +70,7 @@ cc_cipher->decryptor_handle, input.ptr, input.len, out->buffer + out->len, available_write_space, &len_written); if (status != kCCSuccess) { - cipher->good = false; + cipher->state = AWS_SYMMETRIC_CIPHER_ERROR; return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); } @@ -95,7 +95,7 @@ CCCryptorFinal(cc_cipher->encryptor_handle, out->buffer + out->len, available_write_space, &len_written); if (status != kCCSuccess) { - cipher->good = false; + cipher->state = AWS_SYMMETRIC_CIPHER_ERROR; return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); } @@ -120,7 +120,7 @@ CCCryptorFinal(cc_cipher->decryptor_handle, out->buffer + out->len, available_write_space, &len_written); if (status != kCCSuccess) { - cipher->good = false; + cipher->state = AWS_SYMMETRIC_CIPHER_ERROR; return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); } @@ -254,7 +254,7 @@ return NULL; } - cc_cipher->cipher_base.good = true; + cc_cipher->cipher_base.state = AWS_SYMMETRIC_CIPHER_READY; cc_cipher->cipher_base.key_length_bits = AWS_AES_256_KEY_BIT_LEN; return &cc_cipher->cipher_base; @@ -354,7 +354,7 @@ return NULL; } - cc_cipher->cipher_base.good = true; + cc_cipher->cipher_base.state = AWS_SYMMETRIC_CIPHER_READY; cc_cipher->cipher_base.key_length_bits = AWS_AES_256_KEY_BIT_LEN; return &cc_cipher->cipher_base; @@ -414,7 +414,7 @@ size_t tag_length = AWS_AES_256_CIPHER_BLOCK_SIZE; CCStatus status = s_cc_crypto_gcm_finalize(cc_cipher->encryptor_handle, cipher->tag.buffer, tag_length); if (status != kCCSuccess) { - cipher->good = false; + cipher->state = AWS_SYMMETRIC_CIPHER_ERROR; return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); } @@ -430,7 +430,7 @@ size_t tag_length = AWS_AES_256_CIPHER_BLOCK_SIZE; CCStatus status = s_cc_crypto_gcm_finalize(cc_cipher->encryptor_handle, cipher->tag.buffer, tag_length); if (status != kCCSuccess) { - cipher->good = false; + cipher->state = AWS_SYMMETRIC_CIPHER_ERROR; return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); } @@ -584,7 +584,7 @@ return NULL; } - cc_cipher->cipher_base.good = true; + cc_cipher->cipher_base.state = AWS_SYMMETRIC_CIPHER_READY; cc_cipher->cipher_base.key_length_bits = AWS_AES_256_KEY_BIT_LEN; return &cc_cipher->cipher_base; @@ -622,7 +622,7 @@ struct cc_aes_cipher *cc_cipher = cipher->impl; if (cc_cipher->working_buffer.len == 0) { - cipher->good = false; + cipher->state = AWS_SYMMETRIC_CIPHER_ERROR; return aws_raise_error(AWS_ERROR_INVALID_STATE); } @@ -644,7 +644,7 @@ &output_buffer_len); if (status != kCCSuccess) { - cipher->good = false; + cipher->state = AWS_SYMMETRIC_CIPHER_ERROR; return aws_raise_error(AWS_ERROR_INVALID_STATE); } @@ -657,7 +657,7 @@ struct cc_aes_cipher *cc_cipher = cipher->impl; if (cc_cipher->working_buffer.len == 0) { - cipher->good = false; + cipher->state = AWS_SYMMETRIC_CIPHER_ERROR; return aws_raise_error(AWS_ERROR_INVALID_STATE); } @@ -679,7 +679,7 @@ &output_buffer_len); if (status != kCCSuccess) { - cipher->good = false; + cipher->state = AWS_SYMMETRIC_CIPHER_ERROR; return aws_raise_error(AWS_ERROR_INVALID_STATE); } @@ -716,7 +716,7 @@ } aws_byte_buf_init(&cc_cipher->working_buffer, allocator, (AWS_AES_256_CIPHER_BLOCK_SIZE * 2) + 8); - cc_cipher->cipher_base.good = true; + cc_cipher->cipher_base.state = AWS_SYMMETRIC_CIPHER_READY; cc_cipher->cipher_base.key_length_bits = AWS_AES_256_KEY_BIT_LEN; return &cc_cipher->cipher_base; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-cal-0.6.11/source/darwin/securityframework_ecc.c new/aws-c-cal-0.6.13/source/darwin/securityframework_ecc.c --- old/aws-c-cal-0.6.11/source/darwin/securityframework_ecc.c 2024-03-05 01:49:59.000000000 +0100 +++ new/aws-c-cal-0.6.13/source/darwin/securityframework_ecc.c 2024-05-08 22:22:59.000000000 +0200 @@ -7,6 +7,7 @@ #include <aws/cal/cal.h> #include <aws/cal/private/der.h> +#include <CoreFoundation/CoreFoundation.h> #include <Security/SecKey.h> #include <Security/Security.h> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-cal-0.6.11/source/rsa.c new/aws-c-cal-0.6.13/source/rsa.c --- old/aws-c-cal-0.6.11/source/rsa.c 2024-03-05 01:49:59.000000000 +0100 +++ new/aws-c-cal-0.6.13/source/rsa.c 2024-05-08 22:22:59.000000000 +0200 @@ -108,6 +108,7 @@ struct aws_byte_buf *out) { AWS_PRECONDITION(key_pair); AWS_PRECONDITION(out); + AWS_PRECONDITION(aws_byte_cursor_is_valid(&plaintext)); if (AWS_UNLIKELY(aws_rsa_key_pair_max_encrypt_plaintext_size(key_pair, algorithm) < plaintext.len)) { AWS_LOGF_ERROR(AWS_LS_CAL_RSA, "Unexpected buffer size. For RSA, ciphertext must not exceed block size"); @@ -124,6 +125,7 @@ struct aws_byte_buf *out) { AWS_PRECONDITION(key_pair); AWS_PRECONDITION(out); + AWS_PRECONDITION(aws_byte_cursor_is_valid(&ciphertext)); if (AWS_UNLIKELY(ciphertext.len != (key_pair->key_size_in_bits / 8))) { AWS_LOGF_ERROR(AWS_LS_CAL_RSA, "Unexpected buffer size. For RSA, ciphertext is expected to match block size."); @@ -140,6 +142,7 @@ struct aws_byte_buf *out) { AWS_PRECONDITION(key_pair); AWS_PRECONDITION(out); + AWS_PRECONDITION(aws_byte_cursor_is_valid(&digest)); AWS_FATAL_ASSERT( algorithm == AWS_CAL_RSA_SIGNATURE_PKCS1_5_SHA256 || algorithm == AWS_CAL_RSA_SIGNATURE_PSS_SHA256); @@ -159,6 +162,8 @@ struct aws_byte_cursor digest, struct aws_byte_cursor signature) { AWS_PRECONDITION(key_pair); + AWS_PRECONDITION(aws_byte_cursor_is_valid(&digest)); + AWS_PRECONDITION(aws_byte_cursor_is_valid(&signature)); return key_pair->vtable->verify(key_pair, algorithm, digest, signature); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-cal-0.6.11/source/symmetric_cipher.c new/aws-c-cal-0.6.13/source/symmetric_cipher.c --- old/aws-c-cal-0.6.11/source/symmetric_cipher.c 2024-03-05 01:49:59.000000000 +0100 +++ new/aws-c-cal-0.6.13/source/symmetric_cipher.c 2024-05-08 22:22:59.000000000 +0200 @@ -156,11 +156,13 @@ struct aws_byte_cursor to_encrypt, struct aws_byte_buf *out) { + AWS_PRECONDITION(aws_byte_cursor_is_valid(&to_encrypt)); + if (AWS_UNLIKELY(s_check_input_size_limits(cipher, &to_encrypt) != AWS_OP_SUCCESS)) { return AWS_OP_ERR; } - if (cipher->good) { + if (cipher->state == AWS_SYMMETRIC_CIPHER_READY) { return cipher->vtable->encrypt(cipher, to_encrypt, out); } @@ -172,11 +174,13 @@ struct aws_byte_cursor to_decrypt, struct aws_byte_buf *out) { + AWS_PRECONDITION(aws_byte_cursor_is_valid(&to_decrypt)); + if (AWS_UNLIKELY(s_check_input_size_limits(cipher, &to_decrypt) != AWS_OP_SUCCESS)) { return AWS_OP_ERR; } - if (cipher->good) { + if (cipher->state == AWS_SYMMETRIC_CIPHER_READY) { return cipher->vtable->decrypt(cipher, to_decrypt, out); } @@ -184,9 +188,11 @@ } int aws_symmetric_cipher_finalize_encryption(struct aws_symmetric_cipher *cipher, struct aws_byte_buf *out) { - if (cipher->good) { + if (cipher->state == AWS_SYMMETRIC_CIPHER_READY) { int ret_val = cipher->vtable->finalize_encryption(cipher, out); - cipher->good = false; + if (cipher->state != AWS_SYMMETRIC_CIPHER_ERROR) { + cipher->state = AWS_SYMMETRIC_CIPHER_FINALIZED; + } return ret_val; } @@ -194,9 +200,11 @@ } int aws_symmetric_cipher_finalize_decryption(struct aws_symmetric_cipher *cipher, struct aws_byte_buf *out) { - if (cipher->good) { + if (cipher->state == AWS_SYMMETRIC_CIPHER_READY) { int ret_val = cipher->vtable->finalize_decryption(cipher, out); - cipher->good = false; + if (cipher->state != AWS_SYMMETRIC_CIPHER_ERROR) { + cipher->state = AWS_SYMMETRIC_CIPHER_FINALIZED; + } return ret_val; } return aws_raise_error(AWS_ERROR_INVALID_STATE); @@ -205,7 +213,7 @@ int aws_symmetric_cipher_reset(struct aws_symmetric_cipher *cipher) { int ret_val = cipher->vtable->reset(cipher); if (ret_val == AWS_OP_SUCCESS) { - cipher->good = true; + cipher->state = AWS_SYMMETRIC_CIPHER_READY; } return ret_val; @@ -224,7 +232,11 @@ } bool aws_symmetric_cipher_is_good(const struct aws_symmetric_cipher *cipher) { - return cipher->good; + return cipher->state == AWS_SYMMETRIC_CIPHER_READY; +} + +enum aws_symmetric_cipher_state aws_symmetric_cipher_get_state(const struct aws_symmetric_cipher *cipher) { + return cipher->state; } void aws_symmetric_cipher_generate_initialization_vector( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-cal-0.6.11/source/unix/openssl_aes.c new/aws-c-cal-0.6.13/source/unix/openssl_aes.c --- old/aws-c-cal-0.6.11/source/unix/openssl_aes.c 2024-03-05 01:49:59.000000000 +0100 +++ new/aws-c-cal-0.6.13/source/unix/openssl_aes.c 2024-05-08 22:22:59.000000000 +0200 @@ -14,8 +14,21 @@ struct aws_byte_buf working_buffer; }; +static struct aws_byte_cursor s_empty_plain_text = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL(""); + static int s_encrypt(struct aws_symmetric_cipher *cipher, struct aws_byte_cursor input, struct aws_byte_buf *out) { + /* + * Openssl 1.1.1 and its derivatives like aws-lc and boringssl do not handle + * the case of null input of 0 len gracefully in update (it succeeds, but + * finalize after it will fail). Openssl 3.0 fixed this. Other crypto implementations + * do not have similar issue. + * To workaround the issue, replace null cursor with empty cursor. + */ + if (input.len == 0) { + input = s_empty_plain_text; + } + size_t required_buffer_space = input.len + cipher->block_size; if (aws_symmetric_cipher_try_ensure_sufficient_buffer_space(out, required_buffer_space)) { @@ -28,7 +41,7 @@ int len_written = (int)(available_write_space); if (!EVP_EncryptUpdate( openssl_cipher->encryptor_ctx, out->buffer + out->len, &len_written, input.ptr, (int)input.len)) { - cipher->good = false; + cipher->state = AWS_SYMMETRIC_CIPHER_ERROR; return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); } @@ -47,7 +60,7 @@ int len_written = (int)(out->capacity - out->len); if (!EVP_EncryptFinal_ex(openssl_cipher->encryptor_ctx, out->buffer + out->len, &len_written)) { - cipher->good = false; + cipher->state = AWS_SYMMETRIC_CIPHER_ERROR; return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); } @@ -69,8 +82,7 @@ int len_written = (int)available_write_space; if (!EVP_DecryptUpdate( openssl_cipher->decryptor_ctx, out->buffer + out->len, &len_written, input.ptr, (int)input.len)) { - cipher->good = false; - + cipher->state = AWS_SYMMETRIC_CIPHER_ERROR; return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); } @@ -89,7 +101,7 @@ int len_written = (int)out->capacity - out->len; if (!EVP_DecryptFinal_ex(openssl_cipher->decryptor_ctx, out->buffer + out->len, &len_written)) { - cipher->good = false; + cipher->state = AWS_SYMMETRIC_CIPHER_ERROR; return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); } @@ -130,7 +142,7 @@ EVP_CIPHER_CTX_cleanup(openssl_cipher->encryptor_ctx); EVP_CIPHER_CTX_cleanup(openssl_cipher->decryptor_ctx); aws_byte_buf_secure_zero(&openssl_cipher->working_buffer); - cipher->good = true; + cipher->state = AWS_SYMMETRIC_CIPHER_READY; return AWS_OP_SUCCESS; } @@ -215,7 +227,7 @@ goto error; } - cipher->cipher_base.good = true; + cipher->cipher_base.state = AWS_SYMMETRIC_CIPHER_READY; return &cipher->cipher_base; error: @@ -306,7 +318,7 @@ goto error; } - cipher->cipher_base.good = true; + cipher->cipher_base.state = AWS_SYMMETRIC_CIPHER_READY; return &cipher->cipher_base; error: @@ -326,7 +338,7 @@ EVP_CTRL_GCM_GET_TAG, (int)cipher->tag.capacity, cipher->tag.buffer)) { - cipher->good = false; + cipher->state = AWS_SYMMETRIC_CIPHER_ERROR; return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); } cipher->tag.len = AWS_AES_256_CIPHER_BLOCK_SIZE; @@ -466,7 +478,7 @@ goto error; } - cipher->cipher_base.good = true; + cipher->cipher_base.state = AWS_SYMMETRIC_CIPHER_READY; return &cipher->cipher_base; error: @@ -492,7 +504,7 @@ struct openssl_aes_cipher *openssl_cipher = cipher->impl; if (openssl_cipher->working_buffer.len < MIN_CEK_LENGTH_BYTES) { - cipher->good = false; + cipher->state = AWS_SYMMETRIC_CIPHER_ERROR; return aws_raise_error(AWS_ERROR_INVALID_STATE); } @@ -535,7 +547,7 @@ /* encrypt the concatenated A and R[I] and store it in B */ if (!EVP_EncryptUpdate( openssl_cipher->encryptor_ctx, b.buffer, &b_out_len, temp_input.buffer, (int)temp_input.capacity)) { - cipher->good = false; + cipher->state = AWS_SYMMETRIC_CIPHER_ERROR; return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); } @@ -560,7 +572,7 @@ struct openssl_aes_cipher *openssl_cipher = cipher->impl; if (openssl_cipher->working_buffer.len < MIN_CEK_LENGTH_BYTES + KEYWRAP_BLOCK_SIZE) { - cipher->good = false; + cipher->state = AWS_SYMMETRIC_CIPHER_ERROR; return aws_raise_error(AWS_ERROR_INVALID_STATE); } @@ -607,7 +619,7 @@ /* Decrypt the concatenated buffer */ if (!EVP_DecryptUpdate( openssl_cipher->decryptor_ctx, b.buffer, &b_out_len, temp_input.buffer, (int)temp_input.capacity)) { - cipher->good = false; + cipher->state = AWS_SYMMETRIC_CIPHER_ERROR; return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); } @@ -625,7 +637,7 @@ /* here we perform the integrity check to make sure A == 0xA6A6A6A6A6A6A6A6 */ for (size_t i = 0; i < KEYWRAP_BLOCK_SIZE; ++i) { if (a[i] != INTEGRITY_VALUE) { - cipher->good = false; + cipher->state = AWS_SYMMETRIC_CIPHER_ERROR; return aws_raise_error(AWS_ERROR_CAL_SIGNATURE_VALIDATION_FAILED); } } @@ -641,7 +653,7 @@ EVP_CIPHER_CTX_set_padding(openssl_cipher->encryptor_ctx, 0)) || !(EVP_DecryptInit_ex(openssl_cipher->decryptor_ctx, EVP_aes_256_ecb(), NULL, cipher->key.buffer, NULL) && EVP_CIPHER_CTX_set_padding(openssl_cipher->decryptor_ctx, 0))) { - cipher->good = false; + cipher->state = AWS_SYMMETRIC_CIPHER_ERROR; return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); } @@ -701,7 +713,7 @@ goto error; } - cipher->cipher_base.good = true; + cipher->cipher_base.state = AWS_SYMMETRIC_CIPHER_READY; return &cipher->cipher_base; error: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-cal-0.6.11/source/unix/openssl_platform_init.c new/aws-c-cal-0.6.13/source/unix/openssl_platform_init.c --- old/aws-c-cal-0.6.11/source/unix/openssl_platform_init.c 2024-03-05 01:49:59.000000000 +0100 +++ new/aws-c-cal-0.6.13/source/unix/openssl_platform_init.c 2024-05-08 22:22:59.000000000 +0200 @@ -555,8 +555,6 @@ return AWS_LIBCRYPTO_NONE; } -static void *s_libcrypto_module = NULL; - static enum aws_libcrypto_version s_resolve_libcrypto(void) { /* Try to auto-resolve against what's linked in/process space */ AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "searching process and loaded modules"); @@ -644,6 +642,35 @@ #endif } +/* + * Shutdown any resources before unloading CRT (ex. dlclose). + * This is currently aws-lc specific. + * Ex. why we need it: + * aws-lc uses thread local data extensively and registers thread atexit + * callback to clean it up. + * there are cases where crt gets dlopen'ed and then dlclose'ed within a larger program + * (ex. nodejs workers). + * with glibc, dlclose actually removes symbols from global space (musl does not). + * once crt is unloaded, thread atexit will no longer point at a valid aws-lc + * symbol and will happily crash when thread is closed. + * AWSLC_thread_local_shutdown was added by aws-lc to let teams remove thread + * local data manually before lib is unloaded. + * We can't call AWSLC_thread_local_shutdown in cal cleanup because it renders + * aws-lc unusable and there is no way to reinitilize aws-lc to a working state, + * i.e. everything that depends on aws-lc stops working after shutdown (ex. curl). + * So instead rely on GCC/Clang destructor extension to shutdown right before + * crt gets unloaded. Does not work on msvc, but thats a bridge we can cross at + * a later date (since we dont support aws-lc on win right now) + * TODO: do already init'ed check on lc similar to what we do for s2n, so we + * only shutdown when we initialized aws-lc. currently not possible because + * there is no way to check that aws-lc has been initialized. + */ +void __attribute__((destructor)) s_cal_crypto_shutdown(void) { +#if defined(OPENSSL_IS_AWSLC) + AWSLC_thread_local_shutdown(); +#endif +} + void aws_cal_platform_clean_up(void) { #if !defined(OPENSSL_IS_AWSLC) && !defined(OPENSSL_IS_BORINGSSL) if (CRYPTO_get_locking_callback() == s_locking_fn) { @@ -662,13 +689,8 @@ #if defined(OPENSSL_IS_AWSLC) AWSLC_thread_local_clear(); - AWSLC_thread_local_shutdown(); #endif - if (s_libcrypto_module) { - dlclose(s_libcrypto_module); - } - s_libcrypto_allocator = NULL; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-cal-0.6.11/source/windows/bcrypt_aes.c new/aws-c-cal-0.6.13/source/windows/bcrypt_aes.c --- old/aws-c-cal-0.6.11/source/windows/bcrypt_aes.c 2024-03-05 01:49:59.000000000 +0100 +++ new/aws-c-cal-0.6.13/source/windows/bcrypt_aes.c 2024-05-08 22:22:59.000000000 +0200 @@ -210,7 +210,7 @@ cipher->key_handle = s_import_key_blob(cipher->alg_handle, cipher->cipher.allocator, &cipher->cipher.key); if (!cipher->key_handle) { - cipher->cipher.good = false; + cipher->cipher.state = AWS_SYMMETRIC_CIPHER_ERROR; return AWS_OP_ERR; } @@ -228,7 +228,7 @@ 0); if (!NT_SUCCESS(status)) { - cipher->cipher.good = false; + cipher->cipher.state = AWS_SYMMETRIC_CIPHER_ERROR; return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); } } else if (is_gcm) { @@ -358,7 +358,7 @@ cipher_impl->cipher_flags); if (!NT_SUCCESS(status)) { - cipher->good = false; + cipher->state = AWS_SYMMETRIC_CIPHER_ERROR; return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); } @@ -421,7 +421,7 @@ static int s_aes_cbc_finalize_encryption(struct aws_symmetric_cipher *cipher, struct aws_byte_buf *out) { struct aes_bcrypt_cipher *cipher_impl = cipher->impl; - if (cipher->good && cipher_impl->overflow.len > 0) { + if (cipher->state == AWS_SYMMETRIC_CIPHER_READY && cipher_impl->overflow.len > 0) { cipher_impl->cipher_flags = BCRYPT_BLOCK_PADDING; /* take the rest of the overflow and turn padding on so the remainder is properly padded without timing attack vulnerabilities. */ @@ -475,7 +475,7 @@ cipher_impl->cipher_flags); if (!NT_SUCCESS(status)) { - cipher->good = false; + cipher->state = AWS_SYMMETRIC_CIPHER_ERROR; return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); } @@ -498,7 +498,7 @@ static int s_aes_cbc_finalize_decryption(struct aws_symmetric_cipher *cipher, struct aws_byte_buf *out) { struct aes_bcrypt_cipher *cipher_impl = cipher->impl; - if (cipher->good && cipher_impl->overflow.len > 0) { + if (cipher->state == AWS_SYMMETRIC_CIPHER_READY && cipher_impl->overflow.len > 0) { cipher_impl->cipher_flags = BCRYPT_BLOCK_PADDING; /* take the rest of the overflow and turn padding on so the remainder is properly padded without timing attack vulnerabilities. */ @@ -547,7 +547,7 @@ /* make sure the cleanup doesn't do anything. */ cipher->working_iv.allocator = NULL; cipher->cipher.impl = cipher; - cipher->cipher.good = true; + cipher->cipher.state = AWS_SYMMETRIC_CIPHER_READY; return &cipher->cipher; @@ -715,7 +715,7 @@ aws_byte_buf_secure_zero(&cipher->working_iv); cipher->cipher.impl = cipher; - cipher->cipher.good = true; + cipher->cipher.state = AWS_SYMMETRIC_CIPHER_READY; return &cipher->cipher; @@ -831,7 +831,7 @@ cipher_impl->cipher_flags); if (!NT_SUCCESS(status)) { - cipher->good = false; + cipher->state = AWS_SYMMETRIC_CIPHER_ERROR; ret_val = aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); goto clean_up; } @@ -856,7 +856,7 @@ /* check for overflow here. */ if (aws_add_u32_checked(counter, 1, &counter) != AWS_OP_SUCCESS) { - cipher->good = false; + cipher->state = AWS_SYMMETRIC_CIPHER_ERROR; ret_val = AWS_OP_ERR; goto clean_up; } @@ -922,7 +922,7 @@ aws_byte_buf_init_copy(&cipher->working_iv, allocator, &cipher->cipher.iv); cipher->cipher.impl = cipher; - cipher->cipher.good = true; + cipher->cipher.state = AWS_SYMMETRIC_CIPHER_READY; return &cipher->cipher; @@ -964,7 +964,7 @@ key_handle_to_encrypt, cipher_impl->key_handle, BCRYPT_AES_WRAP_KEY_BLOB, NULL, 0, &output_size, 0); if (!NT_SUCCESS(status)) { - cipher->good = false; + cipher->state = AWS_SYMMETRIC_CIPHER_ERROR; return aws_raise_error(AWS_ERROR_INVALID_STATE); } @@ -986,7 +986,7 @@ 0); if (!NT_SUCCESS(status)) { - cipher->good = false; + cipher->state = AWS_SYMMETRIC_CIPHER_ERROR; goto clean_up; } @@ -1057,7 +1057,7 @@ } else { aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); - cipher->good = false; + cipher->state = AWS_SYMMETRIC_CIPHER_ERROR; } clean_up: @@ -1066,7 +1066,7 @@ } else { aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); - cipher->good = false; + cipher->state = AWS_SYMMETRIC_CIPHER_ERROR; } return ret_val; @@ -1111,7 +1111,7 @@ aws_byte_buf_init(&cipher->overflow, allocator, (AWS_AES_256_CIPHER_BLOCK_SIZE * 2) + 8); cipher->cipher.impl = cipher; - cipher->cipher.good = true; + cipher->cipher.state = AWS_SYMMETRIC_CIPHER_READY; return &cipher->cipher; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-cal-0.6.11/tests/CMakeLists.txt new/aws-c-cal-0.6.13/tests/CMakeLists.txt --- old/aws-c-cal-0.6.11/tests/CMakeLists.txt 2024-03-05 01:49:59.000000000 +0100 +++ new/aws-c-cal-0.6.13/tests/CMakeLists.txt 2024-05-08 22:22:59.000000000 +0200 @@ -116,6 +116,7 @@ add_test_case(aes_keywrap_RFC3394_256BitKey128BitCekPayloadCheckFailedTestVector) add_test_case(aes_keywrap_validate_materials_fails) add_test_case(aes_test_input_too_large) +add_test_case(aes_test_encrypt_empty_input) add_test_case(der_encode_integer) add_test_case(der_encode_integer_zero) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-cal-0.6.11/tests/aes256_test.c new/aws-c-cal-0.6.13/tests/aes256_test.c --- old/aws-c-cal-0.6.11/tests/aes256_test.c 2024-03-05 01:49:59.000000000 +0100 +++ new/aws-c-cal-0.6.13/tests/aes256_test.c 2024-05-08 22:22:59.000000000 +0200 @@ -28,11 +28,14 @@ encrypted_buf.len += AWS_AES_256_CIPHER_BLOCK_SIZE; aws_symmetric_cipher_reset(cipher); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_READY, aws_symmetric_cipher_get_state(cipher)); struct aws_byte_cursor encrypted_cur = aws_byte_cursor_from_buf(&encrypted_buf); struct aws_byte_buf decrypted_buf; aws_byte_buf_init(&decrypted_buf, allocator, AWS_AES_256_CIPHER_BLOCK_SIZE); ASSERT_SUCCESS(aws_symmetric_cipher_decrypt(cipher, encrypted_cur, &decrypted_buf)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_READY, aws_symmetric_cipher_get_state(cipher)); ASSERT_SUCCESS(aws_symmetric_cipher_finalize_decryption(cipher, &decrypted_buf)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_FINALIZED, aws_symmetric_cipher_get_state(cipher)); /* finalizing decryption on exactly one block (that was full), should have the padding stripped away. * check that the length didn't increase on that last call. */ @@ -146,9 +149,11 @@ while (encrypted_cur.len) { struct aws_byte_cursor to_decrypt = aws_byte_cursor_advance(&encrypted_cur, (size_t)aws_min_i64(24, encrypted_cur.len)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_READY, aws_symmetric_cipher_get_state(cipher)); ASSERT_SUCCESS(aws_symmetric_cipher_decrypt(cipher, to_decrypt, &decrypted_buf)); } ASSERT_SUCCESS(aws_symmetric_cipher_finalize_decryption(cipher, &decrypted_buf)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_FINALIZED, aws_symmetric_cipher_get_state(cipher)); ASSERT_BIN_ARRAYS_EQUALS(data.ptr, data.len, decrypted_buf.buffer, decrypted_buf.len); aws_byte_buf_clean_up(&decrypted_buf); @@ -239,15 +244,21 @@ aws_byte_buf_init(&encrypted_buf, allocator, AWS_AES_256_CIPHER_BLOCK_SIZE); struct aws_byte_cursor input = aws_byte_cursor_from_c_str(TEST_ENCRYPTION_STRING); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_READY, aws_symmetric_cipher_get_state(cipher)); ASSERT_SUCCESS(aws_symmetric_cipher_encrypt(cipher, input, &encrypted_buf)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_READY, aws_symmetric_cipher_get_state(cipher)); ASSERT_SUCCESS(aws_symmetric_cipher_finalize_encryption(cipher, &encrypted_buf)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_FINALIZED, aws_symmetric_cipher_get_state(cipher)); ASSERT_SUCCESS(aws_symmetric_cipher_reset(cipher)); struct aws_byte_buf decrypted_buf; aws_byte_buf_init(&decrypted_buf, allocator, AWS_AES_256_CIPHER_BLOCK_SIZE); struct aws_byte_cursor encryted_cur = aws_byte_cursor_from_buf(&encrypted_buf); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_READY, aws_symmetric_cipher_get_state(cipher)); ASSERT_SUCCESS(aws_symmetric_cipher_decrypt(cipher, encryted_cur, &decrypted_buf)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_READY, aws_symmetric_cipher_get_state(cipher)); ASSERT_SUCCESS(aws_symmetric_cipher_finalize_decryption(cipher, &decrypted_buf)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_FINALIZED, aws_symmetric_cipher_get_state(cipher)); ASSERT_BIN_ARRAYS_EQUALS(input.ptr, input.len, decrypted_buf.buffer, decrypted_buf.len); @@ -314,8 +325,11 @@ struct aws_byte_cursor encrypted_cur = aws_byte_cursor_from_buf(&encrypted_buf); struct aws_byte_buf decrypted_buf; aws_byte_buf_init(&decrypted_buf, allocator, AWS_AES_256_CIPHER_BLOCK_SIZE); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_READY, aws_symmetric_cipher_get_state(cipher)); ASSERT_SUCCESS(aws_symmetric_cipher_decrypt(cipher, encrypted_cur, &decrypted_buf)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_READY, aws_symmetric_cipher_get_state(cipher)); ASSERT_SUCCESS(aws_symmetric_cipher_finalize_decryption(cipher, &decrypted_buf)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_FINALIZED, aws_symmetric_cipher_get_state(cipher)); ASSERT_BIN_ARRAYS_EQUALS(data.ptr, data.len, decrypted_buf.buffer, decrypted_buf.len); @@ -355,9 +369,11 @@ while (encrypted_cur.len) { struct aws_byte_cursor to_decrypt = aws_byte_cursor_advance(&encrypted_cur, (size_t)aws_min_i64(24, encrypted_cur.len)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_READY, aws_symmetric_cipher_get_state(cipher)); ASSERT_SUCCESS(aws_symmetric_cipher_decrypt(cipher, to_decrypt, &decrypted_buf)); } ASSERT_SUCCESS(aws_symmetric_cipher_finalize_decryption(cipher, &decrypted_buf)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_FINALIZED, aws_symmetric_cipher_get_state(cipher)); ASSERT_BIN_ARRAYS_EQUALS(data.ptr, data.len, decrypted_buf.buffer, decrypted_buf.len); aws_byte_buf_clean_up(&decrypted_buf); @@ -485,8 +501,11 @@ struct aws_byte_cursor encryted_cur = aws_byte_cursor_from_buf(&encrypted_buf); ASSERT_SUCCESS(aws_symmetric_cipher_reset(cipher)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_READY, aws_symmetric_cipher_get_state(cipher)); ASSERT_SUCCESS(aws_symmetric_cipher_decrypt(cipher, encryted_cur, &decrypted_buf)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_READY, aws_symmetric_cipher_get_state(cipher)); ASSERT_SUCCESS(aws_symmetric_cipher_finalize_decryption(cipher, &decrypted_buf)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_FINALIZED, aws_symmetric_cipher_get_state(cipher)); ASSERT_BIN_ARRAYS_EQUALS(input.ptr, input.len, decrypted_buf.buffer, decrypted_buf.len); @@ -570,8 +589,10 @@ struct aws_byte_cursor to_decrypt = aws_byte_cursor_advance(&encrypted_cur, (size_t)aws_min_i64(24, encrypted_cur.len)); ASSERT_SUCCESS(aws_symmetric_cipher_decrypt(cipher, to_decrypt, &decrypted_buf)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_READY, aws_symmetric_cipher_get_state(cipher)); } ASSERT_SUCCESS(aws_symmetric_cipher_finalize_decryption(cipher, &decrypted_buf)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_FINALIZED, aws_symmetric_cipher_get_state(cipher)); ASSERT_BIN_ARRAYS_EQUALS(data.ptr, data.len, decrypted_buf.buffer, decrypted_buf.len); aws_byte_buf_clean_up(&decrypted_buf); @@ -1071,8 +1092,11 @@ struct aws_byte_buf decrypted_buf; aws_byte_buf_init(&decrypted_buf, allocator, AWS_AES_256_CIPHER_BLOCK_SIZE); struct aws_byte_cursor encryted_cur = aws_byte_cursor_from_buf(&encrypted_buf); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_READY, aws_symmetric_cipher_get_state(cipher)); ASSERT_SUCCESS(aws_symmetric_cipher_decrypt(cipher, encryted_cur, &decrypted_buf)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_READY, aws_symmetric_cipher_get_state(cipher)); ASSERT_SUCCESS(aws_symmetric_cipher_finalize_decryption(cipher, &decrypted_buf)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_FINALIZED, aws_symmetric_cipher_get_state(cipher)); ASSERT_BIN_ARRAYS_EQUALS(input.ptr, input.len, decrypted_buf.buffer, decrypted_buf.len); @@ -1155,8 +1179,11 @@ ASSERT_SUCCESS(aws_byte_buf_init(&decrypted_buf, allocator, input_length)); struct aws_byte_cursor encrypted_data = aws_byte_cursor_from_buf(&output_buf); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_READY, aws_symmetric_cipher_get_state(cipher)); ASSERT_SUCCESS(aws_symmetric_cipher_decrypt(cipher, encrypted_data, &decrypted_buf)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_READY, aws_symmetric_cipher_get_state(cipher)); ASSERT_SUCCESS(aws_symmetric_cipher_finalize_decryption(cipher, &decrypted_buf)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_FINALIZED, aws_symmetric_cipher_get_state(cipher)); ASSERT_BIN_ARRAYS_EQUALS(input, input_length, decrypted_buf.buffer, decrypted_buf.len); aws_symmetric_cipher_destroy(cipher); @@ -1205,8 +1232,11 @@ ASSERT_SUCCESS(aws_byte_buf_init(&decrypted_buf, allocator, input_length)); struct aws_byte_cursor encrypted_data = aws_byte_cursor_from_buf(&output_buf); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_READY, aws_symmetric_cipher_get_state(cipher)); ASSERT_SUCCESS(aws_symmetric_cipher_decrypt(cipher, encrypted_data, &decrypted_buf)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_READY, aws_symmetric_cipher_get_state(cipher)); ASSERT_FAILS(aws_symmetric_cipher_finalize_decryption(cipher, &decrypted_buf)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_ERROR, aws_symmetric_cipher_get_state(cipher)); ASSERT_FALSE(aws_symmetric_cipher_is_good(cipher)); aws_symmetric_cipher_destroy(cipher); @@ -1254,8 +1284,11 @@ ASSERT_SUCCESS(aws_byte_buf_init(&decrypted_buf, allocator, input_length)); struct aws_byte_cursor encrypted_data = aws_byte_cursor_from_buf(&output_buf); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_READY, aws_symmetric_cipher_get_state(cipher)); ASSERT_SUCCESS(aws_symmetric_cipher_decrypt(cipher, encrypted_data, &decrypted_buf)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_READY, aws_symmetric_cipher_get_state(cipher)); ASSERT_SUCCESS(aws_symmetric_cipher_finalize_decryption(cipher, &decrypted_buf)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_FINALIZED, aws_symmetric_cipher_get_state(cipher)); ASSERT_BIN_ARRAYS_EQUALS(input, input_length, decrypted_buf.buffer, decrypted_buf.len); aws_symmetric_cipher_destroy(cipher); @@ -1300,8 +1333,11 @@ ASSERT_SUCCESS(aws_byte_buf_init(&decrypted_buf, allocator, input_length)); struct aws_byte_cursor encrypted_data = aws_byte_cursor_from_buf(&output_buf); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_READY, aws_symmetric_cipher_get_state(cipher)); ASSERT_SUCCESS(aws_symmetric_cipher_decrypt(cipher, encrypted_data, &decrypted_buf)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_READY, aws_symmetric_cipher_get_state(cipher)); ASSERT_SUCCESS(aws_symmetric_cipher_finalize_decryption(cipher, &decrypted_buf)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_FINALIZED, aws_symmetric_cipher_get_state(cipher)); aws_symmetric_cipher_destroy(cipher); aws_byte_buf_clean_up(&output_buf); aws_byte_buf_clean_up(&decrypted_buf); @@ -1344,8 +1380,11 @@ struct aws_byte_cursor encrypted_data = aws_byte_cursor_from_buf(&output_buf); encrypted_data.ptr[1] = encrypted_data.ptr[1] + encrypted_data.ptr[2]; + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_READY, aws_symmetric_cipher_get_state(cipher)); ASSERT_SUCCESS(aws_symmetric_cipher_decrypt(cipher, encrypted_data, &decrypted_buf)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_READY, aws_symmetric_cipher_get_state(cipher)); ASSERT_FAILS(aws_symmetric_cipher_finalize_decryption(cipher, &decrypted_buf)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_ERROR, aws_symmetric_cipher_get_state(cipher)); ASSERT_FALSE(aws_symmetric_cipher_is_good(cipher)); aws_symmetric_cipher_destroy(cipher); @@ -1392,8 +1431,11 @@ struct aws_byte_cursor encrypted_data = aws_byte_cursor_from_buf(&output_buf); encrypted_data.ptr[14] = encrypted_data.ptr[13] + encrypted_data.ptr[14]; + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_READY, aws_symmetric_cipher_get_state(cipher)); ASSERT_SUCCESS(aws_symmetric_cipher_decrypt(cipher, encrypted_data, &decrypted_buf)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_READY, aws_symmetric_cipher_get_state(cipher)); ASSERT_FAILS(aws_symmetric_cipher_finalize_decryption(cipher, &decrypted_buf)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_ERROR, aws_symmetric_cipher_get_state(cipher)); ASSERT_FALSE(aws_symmetric_cipher_is_good(cipher)); aws_symmetric_cipher_destroy(cipher); @@ -1445,11 +1487,57 @@ ASSERT_ERROR(AWS_ERROR_CAL_BUFFER_TOO_LARGE_FOR_ALGORITHM, aws_symmetric_cipher_encrypt(cipher, invalid_cur, NULL)); /* should still be good from an invalid input. */ ASSERT_TRUE(aws_symmetric_cipher_is_good(cipher)); + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_READY, aws_symmetric_cipher_get_state(cipher)); ASSERT_ERROR(AWS_ERROR_CAL_BUFFER_TOO_LARGE_FOR_ALGORITHM, aws_symmetric_cipher_decrypt(cipher, invalid_cur, NULL)); /* should still be good from an invalid input. */ + ASSERT_INT_EQUALS(AWS_SYMMETRIC_CIPHER_READY, aws_symmetric_cipher_get_state(cipher)); ASSERT_TRUE(aws_symmetric_cipher_is_good(cipher)); aws_symmetric_cipher_destroy(cipher); return AWS_OP_SUCCESS; } AWS_TEST_CASE(aes_test_input_too_large, s_test_input_too_large_fn) + +static int s_aes_test_encrypt_empty_input(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + + uint8_t iv[] = {0xFB, 0x7B, 0x4A, 0x82, 0x4E, 0x82, 0xDA, 0xA6, 0xC8, 0xBC, 0x12, 0x51}; + + uint8_t key[] = {0x20, 0x14, 0x2E, 0x89, 0x8C, 0xD2, 0xFD, 0x98, 0x0F, 0xBF, 0x34, 0xDE, 0x6B, 0xC8, 0x5C, 0x14, + 0xDA, 0x7D, 0x57, 0xBD, 0x28, 0xF4, 0xAA, 0x5C, 0xF1, 0x72, 0x8A, 0xB6, 0x4E, 0x84, 0x31, 0x42}; + + uint8_t aad[] = {0x16, 0x7B, 0x5C, 0x22, 0x61, 0x77, 0x73, 0x3A, 0x78, 0x2D, 0x61, 0x6D, 0x7A, 0x2D, 0x63, 0x65, + 0x6B, 0x2D, 0x61, 0x6C, 0x67, 0x5C, 0x22, 0x3A, 0x20, 0x5C, 0x22, 0x41, 0x45, 0x53, 0x2F, 0x47, + 0x43, 0x4D, 0x2F, 0x4E, 0x6F, 0x50, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x5C, 0x22, 0x7D}; + + struct aws_byte_cursor key_cur = aws_byte_cursor_from_array(key, sizeof(key)); + struct aws_byte_cursor iv_cur = aws_byte_cursor_from_array(iv, sizeof(iv)); + struct aws_byte_cursor aad_cur = aws_byte_cursor_from_array(aad, sizeof(aad)); + + struct aws_symmetric_cipher *cipher = aws_aes_gcm_256_new(allocator, &key_cur, &iv_cur, &aad_cur, NULL); + + // encrypt + struct aws_byte_cursor data_cur = {0}; + struct aws_byte_buf encrypt_buf = {0}; + aws_byte_buf_init(&encrypt_buf, allocator, AWS_AES_256_CIPHER_BLOCK_SIZE * 2); + ASSERT_SUCCESS(aws_symmetric_cipher_encrypt(cipher, data_cur, &encrypt_buf)); + + // finalize + ASSERT_SUCCESS(aws_symmetric_cipher_finalize_encryption(cipher, &encrypt_buf)); + + ASSERT_INT_EQUALS(0, encrypt_buf.len); + + aws_symmetric_cipher_reset(cipher); + struct aws_byte_buf decrypted_buf = {0}; + aws_byte_buf_init(&decrypted_buf, allocator, AWS_AES_256_CIPHER_BLOCK_SIZE); + struct aws_byte_cursor ciphertext_cur = aws_byte_cursor_from_buf(&encrypt_buf); + ASSERT_SUCCESS(aws_symmetric_cipher_decrypt(cipher, ciphertext_cur, &decrypted_buf)); + ASSERT_SUCCESS(aws_symmetric_cipher_finalize_decryption(cipher, &decrypted_buf)); + + aws_byte_buf_clean_up(&encrypt_buf); + aws_byte_buf_clean_up(&decrypted_buf); + aws_symmetric_cipher_destroy(cipher); + + return AWS_OP_SUCCESS; +} +AWS_TEST_CASE(aes_test_encrypt_empty_input, s_aes_test_encrypt_empty_input)