Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stop using private CommonCrypto APIs on iOS #170

Merged
merged 1 commit into from Oct 30, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
65 changes: 48 additions & 17 deletions source/darwin/commoncrypto_aes.c
Expand Up @@ -9,11 +9,20 @@
#include <CommonCrypto/CommonHMAC.h>
#include <CommonCrypto/CommonSymmetricKeywrap.h>

#include "common_cryptor_spi.h"

#if (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 /* macOS 10.13 */)) || \
(defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* iOS v11 */))
# define USE_LATEST_CRYPTO_API 1
#ifdef AWS_OS_MACOS
/* CommonCrypto does not offer public APIs for doing AES GCM.
* There are private APIs for doing it (CommonCryptoSPI.h), but App Store
* submissions that reference these private symbols will be rejected.
*
* Therefore, enable AES GCM via the private APIs on MacOS builds only,
* iOS, watchOS, etc will have to do without. */
# define SUPPORT_AES_GCM_VIA_SPI 1
# include "common_cryptor_spi.h"

# if (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 /* macOS 10.13 */)) || \
(defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* iOS v11 */))
# define USE_LATEST_CRYPTO_API 1
# endif
#endif

struct cc_aes_cipher {
Expand Down Expand Up @@ -353,43 +362,45 @@ struct aws_symmetric_cipher *aws_aes_ctr_256_new_impl(
return &cc_cipher->cipher_base;
}

#ifdef SUPPORT_AES_GCM_VIA_SPI

/*
* Note that CCCryptorGCMFinal is deprecated in Mac 10.13. It also doesn't compare the tag with expected tag
* https://opensource.apple.com/source/CommonCrypto/CommonCrypto-60118.1.1/include/CommonCryptorSPI.h.auto.html
*/
static CCStatus s_cc_crypto_gcm_finalize(struct _CCCryptor *encryptor_handle, uint8_t *buffer, size_t tag_length) {
#ifdef USE_LATEST_CRYPTO_API
# ifdef USE_LATEST_CRYPTO_API
if (__builtin_available(macOS 10.13, iOS 11.0, *)) {
return CCCryptorGCMFinalize(encryptor_handle, buffer, tag_length);
} else {
/* We would never hit this branch for newer macOS and iOS versions because of the __builtin_available check, so we can
* suppress the compiler warning. */
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
return CCCryptorGCMFinal(encryptor_handle, buffer, &tag_length);
# pragma clang diagnostic pop
# pragma clang diagnostic pop
}
#else
# else
return CCCryptorGCMFinal(encryptor_handle, buffer, &tag_length);

#endif
# endif
}

static CCCryptorStatus s_cc_cryptor_gcm_set_iv(struct _CCCryptor *encryptor_handle, uint8_t *buffer, size_t length) {
#ifdef USE_LATEST_CRYPTO_API
# ifdef USE_LATEST_CRYPTO_API
if (__builtin_available(macOS 10.13, iOS 11.0, *)) {
return CCCryptorGCMSetIV(encryptor_handle, buffer, length);
} else {
/* We would never hit this branch for newer macOS and iOS versions because of the __builtin_available check, so we can
* suppress the compiler warning. */
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
return CCCryptorGCMAddIV(encryptor_handle, buffer, length);
# pragma clang diagnostic pop
# pragma clang diagnostic pop
}
#else
# else
return CCCryptorGCMAddIV(encryptor_handle, buffer, length);
#endif
# endif
}

static int s_finalize_gcm_encryption(struct aws_symmetric_cipher *cipher, struct aws_byte_buf *out) {
Expand Down Expand Up @@ -581,6 +592,26 @@ struct aws_symmetric_cipher *aws_aes_gcm_256_new_impl(
return &cc_cipher->cipher_base;
}

#else /* !SUPPORT_AES_GCM_VIA_SPI */

struct aws_symmetric_cipher *aws_aes_gcm_256_new_impl(
struct aws_allocator *allocator,
const struct aws_byte_cursor *key,
const struct aws_byte_cursor *iv,
const struct aws_byte_cursor *aad,
const struct aws_byte_cursor *tag) {

(void)allocator;
(void)key;
(void)iv;
(void)aad;
(void)tag;
aws_raise_error(AWS_ERROR_PLATFORM_NOT_SUPPORTED);
return NULL;
}

#endif /* SUPPORT_AES_GCM_VIA_SPI */

static int s_keywrap_encrypt_decrypt(
struct aws_symmetric_cipher *cipher,
struct aws_byte_cursor input,
Expand Down