From 3097b1e32a57a5101259281ddb8eeed61939b26e Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Mon, 11 May 2020 18:26:16 +0200 Subject: [PATCH 01/16] Remove support for OpenSSL 1.0.x, it's EOL Change-Id: If860fb8c5f3ea3fc128d52860e923e0cff582cd2 --- src/crypto.c | 103 ++------------------------------------------------------- src/debug.c | 6 ---- src/encrypt.c | 23 ------------- src/internal.h | 25 -------------- 4 files changed, 2 insertions(+), 155 deletions(-) diff --git a/src/crypto.c b/src/crypto.c index 98e941a..585114a 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -44,10 +44,6 @@ #include "internal.h" -#if OPENSSL_VERSION_NUMBER < 0x10100000L -static pthread_mutex_t *mutexes = NULL; -#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ - static __thread bool current_thread_initialized = false; static size_t threads_cnt = 0; static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -82,8 +78,6 @@ static int getrandom_wrapper(unsigned char *buf, int num) return 1; } -#if OPENSSL_VERSION_NUMBER >= 0x10100000L - static int RAND_METHOD_seed(UNUSED const void *buf, UNUSED int num) { return 1; @@ -94,18 +88,6 @@ static int RAND_METHOD_add(UNUSED const void *buf, UNUSED int num, UNUSED double return 1; } -#else /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ - -static void RAND_METHOD_seed(UNUSED const void *buf, UNUSED int num) -{ -} - -static void RAND_METHOD_add(UNUSED const void *buf, UNUSED int num, UNUSED double entropy) -{ -} - -#endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ - static int RAND_METHOD_bytes(unsigned char *buf, int num) { return getrandom_wrapper(buf, num); @@ -141,41 +123,6 @@ static const RAND_METHOD new_rand_method = { RAND_METHOD_status, }; -#if OPENSSL_VERSION_NUMBER < 0x10100000L - -static void locking_callback(int mode, int type, UNUSED const char *file, UNUSED int line) -{ - /* Ignore NULL mutexes and lock/unlock error codes as we can't do anything - * about them. */ - - if (mutexes == NULL) - return; - - if (mode & CRYPTO_LOCK) - pthread_mutex_lock(&mutexes[type]); - else if (mode & CRYPTO_UNLOCK) - pthread_mutex_unlock(&mutexes[type]); -} - -static unsigned long thread_id_callback() -{ - return pthread_self(); -} - -static void destroy_mutexes(int count) -{ - if (mutexes != NULL) { - for (int i = 0; i < count; i++) { - /* Ignore returned value as we can't do anything about it */ - pthread_mutex_destroy(&mutexes[i]); - } - yaca_free(mutexes); - mutexes = NULL; - } -} - -#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ - API int yaca_initialize(void) { int ret = YACA_ERROR_NONE; @@ -225,42 +172,6 @@ API int yaca_initialize(void) OpenSSL_add_all_digests(); OpenSSL_add_all_ciphers(); -#if OPENSSL_VERSION_NUMBER < 0x10100000L - /* enable threads support */ - assert(mutexes == NULL); - - if (CRYPTO_num_locks() > 0) { - ret = yaca_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t), - (void**)&mutexes); - - if (ret != YACA_ERROR_NONE) - goto exit; - - for (int i = 0; i < CRYPTO_num_locks(); i++) { - if (pthread_mutex_init(&mutexes[i], NULL) != 0) { - ret = YACA_ERROR_NONE; - switch (errno) { - case ENOMEM: - ret = YACA_ERROR_OUT_OF_MEMORY; - break; - case EAGAIN: - case EPERM: - case EBUSY: - case EINVAL: - default: - ret = YACA_ERROR_INTERNAL; - } - destroy_mutexes(i); - - goto exit; - } - } - - CRYPTO_set_id_callback(thread_id_callback); - CRYPTO_set_locking_callback(locking_callback); - } -#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ - /* * TODO: * - We should also decide on OpenSSL config. @@ -272,9 +183,9 @@ API int yaca_initialize(void) current_thread_initialized = true; } -#if OPENSSL_VERSION_NUMBER < 0x10100000L || !defined SYS_getrandom +#if !defined SYS_getrandom exit: -#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L || !defined SYS_getrandom */ +#endif /* !defined SYS_getrandom */ pthread_mutex_unlock(&init_mutex); @@ -288,9 +199,6 @@ API void yaca_cleanup(void) return; /* per thread cleanup */ -#if OPENSSL_VERSION_NUMBER < 0x10100000L - ERR_remove_thread_state(NULL); -#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ CRYPTO_cleanup_all_ex_data(); pthread_mutex_lock(&init_mutex); @@ -307,13 +215,6 @@ API void yaca_cleanup(void) urandom_fd = -2; #endif /* SYS_getrandom */ -#if OPENSSL_VERSION_NUMBER < 0x10100000L - /* threads support cleanup */ - CRYPTO_set_id_callback(NULL); - CRYPTO_set_locking_callback(NULL); - - destroy_mutexes(CRYPTO_num_locks()); -#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ } assert(threads_cnt > 0); diff --git a/src/debug.c b/src/debug.c index fbb4dc2..486180e 100644 --- a/src/debug.c +++ b/src/debug.c @@ -127,18 +127,12 @@ int error_handle(const char *file, int line, const char *function) /* known errors */ switch (err) { -#if OPENSSL_VERSION_NUMBER > 0x10100000L case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN): case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN): case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_DATA_TOO_LARGE_FOR_MODULUS): case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_DATA_TOO_LARGE_FOR_MODULUS): case ERR_PACK(ERR_LIB_PEM, PEM_F_GET_NAME, PEM_R_NO_START_LINE): case ERR_PACK(ERR_LIB_PEM, PEM_F_GET_HEADER_AND_DATA, PEM_R_BAD_END_LINE): -#else /* OPENSSL_VERSION_NUMBER > 0x10100000L */ - case ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_KEYBITS): - case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN): - case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN): -#endif /* OPENSSL_VERSION_NUMBER > 0x10100000L */ case ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_CTRL, RSA_R_KEY_SIZE_TOO_SMALL): case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED): case ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_READ_BIO, PEM_R_NO_START_LINE): diff --git a/src/encrypt.c b/src/encrypt.c index 51ca1a9..82f5d77 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -526,13 +526,6 @@ static int encrypt_ctx_setup(struct yaca_encrypt_context_s *c, if (ret != YACA_ERROR_NONE) return ret; -#if OPENSSL_VERSION_NUMBER < 0x10100000L - /* Fix for OpenSSL error in 3DES CFB1 */ - int nid = EVP_CIPHER_CTX_nid(c->cipher_ctx); - if (nid == NID_des_ede3_cfb1) - EVP_CIPHER_CTX_set_flags(c->cipher_ctx, EVP_CIPH_FLAG_LENGTH_BITS); -#endif - if (liv != NULL) iv_data = (unsigned char*)liv->d; @@ -1109,13 +1102,6 @@ int encrypt_update(yaca_context_h ctx, } } - /* Fix for OpenSSL error in 3DES CFB1 */ - if (EVP_CIPHER_CTX_test_flags(c->cipher_ctx, EVP_CIPH_FLAG_LENGTH_BITS) != 0) { - if (input_len > INT_MAX / 8) - return YACA_ERROR_INVALID_PARAMETER; - input_len *= 8; - } - ret = EVP_CipherUpdate(c->cipher_ctx, output, &loutput_len, input, input_len); if (ret != 1 || loutput_len < 0) { if (mode == EVP_CIPH_CCM_MODE && (op_type == OP_DECRYPT || op_type == OP_OPEN)) { @@ -1135,11 +1121,6 @@ int encrypt_update(yaca_context_h ctx, *output_len = loutput_len; c->state = target_state; - - /* Fix for OpenSSL error in 3DES CFB1 */ - if (EVP_CIPHER_CTX_test_flags(c->cipher_ctx, EVP_CIPH_FLAG_LENGTH_BITS) != 0) - *output_len /= 8; - return YACA_ERROR_NONE; } @@ -1175,10 +1156,6 @@ int encrypt_finalize(yaca_context_h ctx, *output_len = loutput_len; - /* Fix for OpenSSL error in 3DES CFB1 */ - if (EVP_CIPHER_CTX_test_flags(c->cipher_ctx, EVP_CIPH_FLAG_LENGTH_BITS) != 0) - *output_len /= 8; - c->state = ENC_CTX_FINALIZED; return YACA_ERROR_NONE; } diff --git a/src/internal.h b/src/internal.h index 7cc5641..b395b66 100644 --- a/src/internal.h +++ b/src/internal.h @@ -41,31 +41,6 @@ #define API __attribute__ ((visibility("default"))) #define UNUSED __attribute__((unused)) -/* Functions that handle the hidden nature of internal - * OpenSSL structures that don't exist in OpenSSL < 1.1.0 - */ -#if OPENSSL_VERSION_NUMBER < 0x10100000L - -static inline EVP_PKEY_CTX *EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx) -{ - return ctx->pctx; -} - -static inline int EVP_PKEY_up_ref(EVP_PKEY *pkey) -{ - if (CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY) <= 0) - return 0; - return 1; -} - -static inline RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey) -{ - if (pkey->type != EVP_PKEY_RSA) - return NULL; - return pkey->pkey.rsa; -} - -#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ enum yaca_context_type_e { YACA_CONTEXT_INVALID = 0, -- 2.7.4 From 71cd0b9a8afeed0ce309d8d4fcee48f2ced0fe34 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Tue, 12 May 2020 14:57:29 +0200 Subject: [PATCH 02/16] Remove unused OpenSSL RAND methods According to docs we can pass NULL to the functions we don't want/need in RAND_METHOD struct. As we don't use them, drop those unneeded. RAND_pseudo_bytes() was deprecated in OpenSSL 1.1.0. Change-Id: Id28795119d6efdd11664d1d81be0524d87e987cf --- src/crypto.c | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/src/crypto.c b/src/crypto.c index 585114a..b798196 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -78,30 +78,11 @@ static int getrandom_wrapper(unsigned char *buf, int num) return 1; } -static int RAND_METHOD_seed(UNUSED const void *buf, UNUSED int num) -{ - return 1; -} - -static int RAND_METHOD_add(UNUSED const void *buf, UNUSED int num, UNUSED double entropy) -{ - return 1; -} - static int RAND_METHOD_bytes(unsigned char *buf, int num) { return getrandom_wrapper(buf, num); } -static void RAND_METHOD_cleanup(void) -{ -} - -static int RAND_METHOD_pseudorand(UNUSED unsigned char *buf, UNUSED int num) -{ - return getrandom_wrapper(buf, num); -} - static int RAND_METHOD_status(void) { #ifdef SYS_getrandom @@ -115,11 +96,11 @@ static int RAND_METHOD_status(void) } static const RAND_METHOD new_rand_method = { - RAND_METHOD_seed, + NULL, RAND_METHOD_bytes, - RAND_METHOD_cleanup, - RAND_METHOD_add, - RAND_METHOD_pseudorand, + NULL, + NULL, + NULL, RAND_METHOD_status, }; -- 2.7.4 From 04eb57b0dd89e74feace9dec903006b50208a04f Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Wed, 17 Jun 2020 18:19:54 +0200 Subject: [PATCH 03/16] Handle errors from EVP_PKEY_CTX_set_* Not every error from EVP_PKEY_CTX_set_* is INTERNAL. Some should be handled lightly like trying to set DH key with bit_len < 256. Change-Id: I5993c8d04600ae1e5b0851d924087704c58c0f9c --- src/key.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/key.c b/src/key.c index 256806b..17afc7c 100644 --- a/src/key.c +++ b/src/key.c @@ -1201,8 +1201,7 @@ static int generate_evp_pkey_params(int evp_id, size_t key_bit_len, EVP_PKEY **p break; } if (ret != 1) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); + ret = ERROR_HANDLE(); goto exit; } -- 2.7.4 From a8929ac54c843e43def74155a2986c63c7831353 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Thu, 18 Jun 2020 17:53:32 +0200 Subject: [PATCH 04/16] Padding has to be set before update in case of decryption When doing encrypt/seal padding can be set before finalize as was before. But it appears that decrypt behaves differently. In that case padding has to be set before update or the decryption will be incorrect. Change-Id: I86ede38d0d79d401329c25c656e5c6b4c92e02cb --- api/yaca/yaca_types.h | 8 ++++++-- src/encrypt.c | 3 ++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/api/yaca/yaca_types.h b/api/yaca/yaca_types.h index a4ae309..65b758a 100644 --- a/api/yaca/yaca_types.h +++ b/api/yaca/yaca_types.h @@ -456,7 +456,9 @@ typedef enum { * Padding can be disabled using yaca_context_set_property() and * #YACA_PROPERTY_PADDING,#YACA_PADDING_NONE, * then the total length of data passed until *_finalize() MUST be a multiple of block size. - * #YACA_PROPERTY_PADDING can be set at the latest before the *_finalize() call. + * In case of encrypt/seal #YACA_PROPERTY_PADDING can be set at the + * latest before the *_finalize() call. In case of decrypt/open + * it can be set at the latest before the *_update() call. */ YACA_BCM_ECB, @@ -475,7 +477,9 @@ typedef enum { * Padding can be disabled using yaca_context_set_property() and * #YACA_PROPERTY_PADDING, #YACA_PADDING_NONE, * then the total length of data passed until *_finalize() MUST be a multiple of block size. - * #YACA_PROPERTY_PADDING can be set at the latest before the *_finalize() call. + * In case of encrypt/seal #YACA_PROPERTY_PADDING can be set at the + * latest before the *_finalize() call. In case of decrypt/open + * it can be set at the latest before the *_update() call. */ YACA_BCM_CBC, diff --git a/src/encrypt.c b/src/encrypt.c index 82f5d77..9c6a1a2 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -808,7 +808,8 @@ static int set_encrypt_property(yaca_context_h ctx, value_len != sizeof(yaca_padding_e) || (*(yaca_padding_e*)value != YACA_PADDING_NONE && *(yaca_padding_e*)value != YACA_PADDING_PKCS7) || - c->state == ENC_CTX_FINALIZED) + ((is_encryption_op(c->op_type)) && c->state == ENC_CTX_FINALIZED) || + (!(is_encryption_op(c->op_type)) && c->state != ENC_CTX_INITIALIZED)) return YACA_ERROR_INVALID_PARAMETER; int padding = *(yaca_padding_e*)value == YACA_PADDING_NONE ? 0 : 1; -- 2.7.4 From a97af8d086e04e29435dcaf836a13b40df655ec1 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Fri, 19 Jun 2020 15:25:52 +0200 Subject: [PATCH 05/16] Distinguish different cases with the same OpenSSL error code When importing a key with a wrong password and decrypting data with wrong key/bcm or simply broken data OpenSSL can return exactly the same error code (ERR_LIB_EVP, EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT). As we need to distinguish INVALID_PARAM and INVALID_PASS in import_key, but decryption cannot return INVALID_PASS handle this manually in the decryption. Change-Id: Iba2b5fccfb1660c20b76a345bc799a0b145d700c --- src/encrypt.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/encrypt.c b/src/encrypt.c index 9c6a1a2..27632f8 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -1144,14 +1144,23 @@ int encrypt_finalize(yaca_context_h ctx, if (mode != EVP_CIPH_WRAP_MODE && mode != EVP_CIPH_CCM_MODE) { ret = EVP_CipherFinal(c->cipher_ctx, output, &loutput_len); if (ret != 1 || loutput_len < 0) { - if (mode == EVP_CIPH_GCM_MODE && (op_type == OP_DECRYPT || op_type == OP_OPEN)) - /* A non positive return value from EVP_CipherFinal should be considered as - * a failure to authenticate ciphertext and/or AAD. - * It does not necessarily indicate a more serious error. - */ + if (mode == EVP_CIPH_GCM_MODE && (op_type == OP_DECRYPT || op_type == OP_OPEN)) { + /* A non positive return value from EVP_CipherFinal should be + * considered as a failure to authenticate ciphertext and/or + * AAD. It does not necessarily indicate a more serious error. + */ return YACA_ERROR_INVALID_PARAMETER; - else - return ERROR_HANDLE(); + } else { + /* The same error code is used if trying to import a key with a + * wrong password and in case of a decrypt error due to wrong + * BCM or a key. Finalize cannot return INVALID_PASS so handle + * this here. + */ + ret = ERROR_HANDLE(); + if (ret == YACA_ERROR_INVALID_PASSWORD) + ret = YACA_ERROR_INVALID_PARAMETER; + return ret; + } } } -- 2.7.4 From e565760f2d59be2dd4b871410ecbf63718c5da41 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Fri, 19 Jun 2020 15:35:07 +0200 Subject: [PATCH 06/16] Clarify possible AAD length Change-Id: I86f83db0c144508fbca593be27bb9c558a69a195 --- api/yaca/yaca_types.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/api/yaca/yaca_types.h b/api/yaca/yaca_types.h index 65b758a..ea602bf 100644 --- a/api/yaca/yaca_types.h +++ b/api/yaca/yaca_types.h @@ -499,6 +499,7 @@ typedef enum { * Set after yaca_decrypt_update() / yaca_open_update() and before * yaca_decrypt_finalize() / yaca_open_finalize() in decryption / open operation.\n * - #YACA_PROPERTY_GCM_AAD = additional authentication data (optional)\n + * AAD length can have any positive value.\n * Set after yaca_encrypt_initialize() / yaca_seal_initialize() and before * yaca_encrypt_update() / yaca_seal_update() in encryption / seal operation.\n * Set after yaca_decrypt_initialize() / yaca_open_initialize() and before @@ -553,6 +554,7 @@ typedef enum { * Set after yaca_decrypt_initialize() / yaca_open_initialize() and before * yaca_decrypt_update() / yaca_open_update() in decryption / open operation.\n * - #YACA_PROPERTY_CCM_AAD = additional authentication data (optional)\n + * AAD length can have any positive value.\n * The total plaintext length must be passed to yaca_encrypt_update() / yaca_seal_update() * if AAD is used.\n * Set after yaca_encrypt_initialize() / yaca_seal_initialize() and before -- 2.7.4 From 8dcd66e4d5c1bf43c71a98eb9e2f3c74503e8977 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Fri, 19 Jun 2020 15:48:48 +0200 Subject: [PATCH 07/16] Clarify calling update only once with CCM When using BCM_CCM yaca update function can be called only once for the plaintext or ciphertext regardless of using AAD. Clarify that in the docs. Change-Id: I350404dd0be10dd7c70d565e60a73497b6601de7 --- api/yaca/yaca_types.h | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/api/yaca/yaca_types.h b/api/yaca/yaca_types.h index ea602bf..ec32158 100644 --- a/api/yaca/yaca_types.h +++ b/api/yaca/yaca_types.h @@ -504,8 +504,9 @@ typedef enum { * yaca_encrypt_update() / yaca_seal_update() in encryption / seal operation.\n * Set after yaca_decrypt_initialize() / yaca_open_initialize() and before * yaca_decrypt_update() / yaca_open_update() in decryption / open operation.\n - * @see yaca_context_set_property() - * @see yaca_context_get_property() + * . + * @see yaca_context_set_property() + * @see yaca_context_get_property() */ YACA_BCM_GCM, @@ -559,16 +560,17 @@ typedef enum { * if AAD is used.\n * Set after yaca_encrypt_initialize() / yaca_seal_initialize() and before * yaca_encrypt_update() / yaca_seal_update() in encryption / seal operation.\n - * You can only call yaca_encrypt_update() / yaca_seal_update() once for AAD - * and once for the plaintext.\n * The total encrypted text length must be passed to yaca_decrypt_update() / * yaca_open_update() if AAD is used.\n * Set after yaca_decrypt_initialize() / yaca_open_initialize() and before * yaca_decrypt_update() / yaca_open_update() in decryption / open operation.\n - * You can only call yaca_decrypt_update() / yaca_open_update() once for AAD - * and once for the encrypted text.\n - * @see yaca_context_set_property() - * @see yaca_context_get_property() + * . + * You can only call yaca_encrypt_update() / yaca_seal_update() once for AAD (if used) + * and once for the plaintext.\n + * You can only call yaca_decrypt_update() / yaca_open_update() once for AAD (if used) + * and once for the encrypted text.\n + * @see yaca_context_set_property() + * @see yaca_context_get_property() */ YACA_BCM_CCM, -- 2.7.4 From 1098d368d387b25034a6d8e2ba850dd656d67f63 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Fri, 19 Jun 2020 17:32:18 +0200 Subject: [PATCH 08/16] Clarify bit_length for yaca_key_generate Add info about symmetric keys and fix DH prime length that has to be >= 256 (OpenSSL requires that). Change-Id: Ic5704d88a103a30dd5c8742a87f4e08e2f54c5f7 --- api/yaca/yaca_key.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api/yaca/yaca_key.h b/api/yaca/yaca_key.h index 7ac0642..8abf4d1 100644 --- a/api/yaca/yaca_key.h +++ b/api/yaca/yaca_key.h @@ -185,11 +185,13 @@ int yaca_key_export(const yaca_key_h key, yaca_key_format_e key_fmt, yaca_key_fi * @remarks This function is used to generate symmetric keys, private asymmetric keys * or key generation parameters for key types that support them (DSA, DH and EC). * @remarks Supported key lengths: + * - SYMMETRIC/IV: >= 8bits + * - DES: 64, 128 or 192bits * - RSA: length >= 512bits * - DSA: length >= 512bits, multiple of 64 * - DH: a value taken from #yaca_key_bit_length_dh_rfc_e or * (YACA_KEY_LENGTH_DH_GENERATOR_* | prime_length_in_bits), - * where prime_length_in_bits can be any positive number + * where prime_length_in_bits has to be >= 256 * - EC: a value taken from #yaca_key_bit_length_ec_e * @remarks The @a key should be released using yaca_key_destroy(). * @param[in] key_type Type of the key to be generated -- 2.7.4 From 85d7d78440e9e53511198e2dbfd37f38e1af6727 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Tue, 23 Jun 2020 14:23:16 +0200 Subject: [PATCH 09/16] Assert instead of error check EVP_CIPHER_CTX_cipher() Functions/macros like EVP_CIPHER_CTX_mode() or EVP_CIPHER_CTX_nid() never error check for cipher inside context being NULL. If ctx is initialized properly (EVP_CIPHER_CTX_new() + EVP_CipherInit_ex()) cipher will not be NULL. If it is it's yaca's error. So assert instead of error check. This error check caused problems for mocking up because the code assumed in this place that EVP_CIPHER_CTX_cipher() can return NULL, while in other it assumed that it cannot (inside EVP_CIPHER_CTX_mode() which is a macro that uses EVP_CIPHER_CTX_cipher()). Change-Id: I1775b85c0949d66e48e157ea8d602ae3c1298d82 --- src/encrypt.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/encrypt.c b/src/encrypt.c index 27632f8..49a4a4d 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -511,11 +511,7 @@ static int encrypt_ctx_setup(struct yaca_encrypt_context_s *c, assert(key != YACA_KEY_NULL); const EVP_CIPHER *cipher = EVP_CIPHER_CTX_cipher(c->cipher_ctx); - if (cipher == NULL) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); - return ret; - } + assert(cipher != NULL); lkey = key_get_simple(key); assert(lkey != NULL); -- 2.7.4 From 3c610ede0d8829b75cc6e583f23dd06ec5187d96 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Tue, 23 Jun 2020 14:27:00 +0200 Subject: [PATCH 10/16] Assert prime_len instead of error check It's impossible now that it'll be larger than INT_MAX. No need to check that. Change-Id: I64bd04d13a46430cef3e969e79b60e2fb8a77e1b --- src/key.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/key.c b/src/key.c index 17afc7c..68def62 100644 --- a/src/key.c +++ b/src/key.c @@ -1123,10 +1123,9 @@ static int generate_evp_pkey_params(int evp_id, size_t key_bit_len, EVP_PKEY **p size_t gen_block = key_bit_len & YACA_KEYLEN_COMPONENT_DH_GEN_MASK; size_t prime_len_block = key_bit_len & YACA_KEYLEN_COMPONENT_DH_PRIME_MASK; - /* This is impossible now as we take only 16 bits, - * but for the sake of type safety */ - if (prime_len_block > INT_MAX) - return YACA_ERROR_INVALID_PARAMETER; + /* This is impossible for now as we take only 16 bits + * but just to be sure for the future */ + assert(prime_len_block <= INT_MAX); dh_prime_len = prime_len_block; if (gen_block == YACA_KEYLEN_COMPONENT_DH_GEN_2) -- 2.7.4 From 594db7dbdf1e2a3a73680b9a1d798888bd5d7dd0 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Thu, 2 Apr 2020 17:41:05 +0200 Subject: [PATCH 11/16] Unit and system tests for YACA Tests that aim to thoroughly test and cover YACA's code. Whole functionality, most combinations of correct and incorrect parameters. Those tests cover >80% of the code, leaving only error handlers from OpenSSL errors. Change-Id: Ieb29f7adaf1edeb30f653c43fb46a2324bdcb040 --- CMakeLists.txt | 3 + packaging/yaca.spec | 13 + tests/CMakeLists.txt | 58 ++ tests/common.cpp | 205 +++++ tests/common.h | 92 ++ tests/test_crypto.cpp | 334 +++++++ tests/test_debug.cpp | 218 +++++ tests/test_digest.cpp | 190 ++++ tests/test_encrypt.cpp | 2402 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/test_key.cpp | 1448 +++++++++++++++++++++++++++++ tests/test_rsa.cpp | 598 ++++++++++++ tests/test_seal.cpp | 1683 +++++++++++++++++++++++++++++++++ tests/test_sign.cpp | 950 +++++++++++++++++++ tests/test_simple.cpp | 755 +++++++++++++++ 14 files changed, 8949 insertions(+) create mode 100644 tests/CMakeLists.txt create mode 100644 tests/common.cpp create mode 100644 tests/common.h create mode 100644 tests/test_crypto.cpp create mode 100644 tests/test_debug.cpp create mode 100644 tests/test_digest.cpp create mode 100644 tests/test_encrypt.cpp create mode 100644 tests/test_key.cpp create mode 100644 tests/test_rsa.cpp create mode 100644 tests/test_seal.cpp create mode 100644 tests/test_sign.cpp create mode 100644 tests/test_simple.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ec14e13..2c1a1f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,6 +55,7 @@ MESSAGE(STATUS "-------------------------------------------------") SET(CMAKE_C_FLAGS_DEBUG "-std=c11 -O0 -ggdb -Wp,-U_FORTIFY_SOURCE") SET(CMAKE_C_FLAGS_RELEASE "-std=c11 -O2 -DNDEBUG") SET(CMAKE_C_FLAGS_COVERAGE "-std=c11 -O0 -ggdb --coverage -Wp,-U_FORTIFY_SOURCE") +SET(CMAKE_CXX_FLAGS_COVERAGE "-std=c++14 -O0 -ggdb --coverage -Wp,-U_FORTIFY_SOURCE") ADD_DEFINITIONS("-fPIC") # Position Independent Code ADD_DEFINITIONS("-Werror") # Make all warnings into errors @@ -75,6 +76,7 @@ ENDIF() SET(API_FOLDER ${PROJECT_SOURCE_DIR}/api/yaca) SET(EXAMPLES_FOLDER ${PROJECT_SOURCE_DIR}/examples) SET(SRC_FOLDER ${PROJECT_SOURCE_DIR}/src) +SET(TESTS_FOLDER ${PROJECT_SOURCE_DIR}/tests) SET(PYTHON_FOLDER ${PROJECT_SOURCE_DIR}/python) IF(NOT DEFINED LIB_INSTALL_DIR) @@ -101,6 +103,7 @@ CONFIGURE_FILE(packaging/yaca.manifest.in yaca.manifest @ONLY) ADD_SUBDIRECTORY(${SRC_FOLDER}) ADD_SUBDIRECTORY(${EXAMPLES_FOLDER}) +ADD_SUBDIRECTORY(${TESTS_FOLDER}) IF(NOT WITHOUT_PYTHON) ADD_SUBDIRECTORY(${PYTHON_FOLDER}) ENDIF(NOT WITHOUT_PYTHON) diff --git a/packaging/yaca.spec b/packaging/yaca.spec index 4f9cd02..7802567 100644 --- a/packaging/yaca.spec +++ b/packaging/yaca.spec @@ -11,6 +11,7 @@ BuildRequires: cmake BuildRequires: python3 >= 3.4 BuildRequires: pkgconfig(capi-base-common) BuildRequires: pkgconfig(openssl1.1) +BuildRequires: boost-devel %if %{build_type} == "COVERAGE" BuildRequires: lcov %endif @@ -83,6 +84,18 @@ The package provides Yet Another Crypto API example files. %{_bindir}/yaca-example* %{_datadir}/%{name}/examples +## Tests Package ############################################################ +%package tests +Summary: Yet Another Crypto API tests +Group: Security/Other +Requires: yaca = %{version}-%{release} + +%description tests +The package provides Yet Another Crypto API unit tests. + +%files tests +%{_bindir}/yaca-unit-tests* + ## Python3 Package ############################################################ %package -n python3-yaca Summary: Yet Another Crypto API Python3 bindings diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..4ebee1a --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,58 @@ +# +# Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved +# +# Contact: Krzysztof Jackiewicz +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License +# +# +# @file CMakeLists.txt +# @author Lukasz Pawelczyk (l.pawelczyk@samsung.com) +# + +SET(TESTS_NAME yaca-unit-tests) +FILE(GLOB YACA_SOURCES ${SRC_FOLDER}/*.c) +SET(TESTS_SOURCES + common.cpp + test_debug.cpp + test_crypto.cpp + test_key.cpp + test_simple.cpp + test_rsa.cpp + test_digest.cpp + test_encrypt.cpp + test_seal.cpp + test_sign.cpp + ) + +FIND_PACKAGE(Boost REQUIRED unit_test_framework) +ADD_DEFINITIONS("-DBOOST_TEST_DYN_LINK") + +INCLUDE_DIRECTORIES(${API_FOLDER} ${SRC_FOLDER}) +INCLUDE_DIRECTORIES(SYSTEM ${YACA_DEPS_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) + +ADD_EXECUTABLE(${TESTS_NAME} ${YACA_SOURCES} ${TESTS_SOURCES}) +TARGET_LINK_LIBRARIES(${TESTS_NAME} + ${YACA_DEPS_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT} + ${Boost_LIBRARIES}) + +INSTALL(TARGETS ${TESTS_NAME} + DESTINATION ${BIN_INSTALL_DIR} + PERMISSIONS OWNER_READ + OWNER_WRITE + OWNER_EXECUTE + GROUP_READ + GROUP_EXECUTE + WORLD_READ + WORLD_EXECUTE) diff --git a/tests/common.cpp b/tests/common.cpp new file mode 100644 index 0000000..e7b5db3 --- /dev/null +++ b/tests/common.cpp @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Pawelczyk + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file common.cpp + * @author Lukasz Pawelczyk + * @brief Common code for YACA unit tests + */ + +#define BOOST_TEST_MODULE YacaUnitTests + +#include +#include +#include +#include + +#include +#include +#include +#include +#include "../src/debug.h" + +#include "common.h" + + +namespace { + +size_t error_cb_called = 0; + +void debug_error_cb(const char *buf) +{ + std::cout << buf; + ++error_cb_called; +} + +} // namespace + + +DebugFixture::DebugFixture() +{ + error_cb_called = 0; + yaca_debug_set_error_cb(&debug_error_cb); +} + +DebugFixture::~DebugFixture() +{ + /* No ERROR_DUMP should've been called. If there is one that is + * harmless (that happens) it should be added to error_handle + * anyway. + */ + BOOST_REQUIRE(error_cb_called == 0); + yaca_debug_set_error_cb(NULL); +} + +InitFixture::InitFixture() +{ + int ret = yaca_initialize(); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); +} + +InitFixture::~InitFixture() +{ + yaca_cleanup(); +} + +struct TestConfig { + TestConfig() + { + boost::unit_test::unit_test_log.set_threshold_level( + boost::unit_test::log_test_units); + boost::unit_test::results_reporter::set_level(boost::unit_test::SHORT_REPORT); + } + ~TestConfig() + { + } +}; + +BOOST_GLOBAL_FIXTURE(TestConfig); + +namespace { + +struct key_types { + yaca_key_type_e pub; + yaca_key_type_e params; +}; + +const std::map KEY_TYPES = { + {YACA_KEY_TYPE_RSA_PRIV, {YACA_KEY_TYPE_RSA_PUB, YACA_INVALID_KEY_TYPE}}, + {YACA_KEY_TYPE_DSA_PRIV, {YACA_KEY_TYPE_DSA_PUB, YACA_KEY_TYPE_DSA_PARAMS}}, + {YACA_KEY_TYPE_DH_PRIV, {YACA_KEY_TYPE_DH_PUB, YACA_KEY_TYPE_DH_PARAMS}}, + {YACA_KEY_TYPE_EC_PRIV, {YACA_KEY_TYPE_EC_PUB, YACA_KEY_TYPE_EC_PARAMS}}, +}; + +} // namespace + +void generate_asymmetric_keys(yaca_key_type_e type_prv, size_t key_bit_len, + yaca_key_h *key_prv, yaca_key_h *key_pub, yaca_key_h *key_params) +{ + int ret; + yaca_key_type_e type_pub, type_params; + yaca_key_h prv, pub, params; + type_pub = type_params = YACA_INVALID_KEY_TYPE; + prv = pub = params = YACA_KEY_NULL; + + BOOST_REQUIRE_NO_THROW(type_pub = KEY_TYPES.at(type_prv).pub); + BOOST_REQUIRE_NO_THROW(type_params = KEY_TYPES.at(type_prv).params); + + ret = yaca_key_generate(type_prv, key_bit_len, &prv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + if (key_pub != NULL && type_pub != YACA_INVALID_KEY_TYPE) { + ret = yaca_key_extract_public(prv, &pub); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + if (key_params != NULL && type_params != YACA_INVALID_KEY_TYPE) { + ret = yaca_key_extract_parameters(prv, ¶ms); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + if (key_prv != NULL) + *key_prv = prv; + else + yaca_key_destroy(prv); + + if (key_pub != NULL) + *key_pub = pub; + + if (key_params != NULL) + *key_params = params; +} + +size_t allocate_output(yaca_context_h ctx, size_t input_len, size_t split, char *&output) +{ + BOOST_REQUIRE_MESSAGE(split >= 1, "Fix your test"); + + int ret; + size_t part = input_len / split; + size_t parts = part * split; + size_t len1 = 0, len2 = 0, len3 = 0; + + BOOST_REQUIRE_MESSAGE(part >= 1, "Fix your test"); + + ret = yaca_context_get_output_length(ctx, part, &len1); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + if (parts < input_len) { + ret = yaca_context_get_output_length(ctx, input_len - parts, &len2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + ret = yaca_context_get_output_length(ctx, 0, &len3); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + size_t total = len1 * split + len2 + len3; + + ret = yaca_zalloc(total, reinterpret_cast(&output)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + return total; +} + +void call_update_loop(yaca_context_h ctx, const char *input, size_t input_len, + char *output, size_t &output_len, size_t split, + update_fun_5_t *fun) +{ + BOOST_REQUIRE_MESSAGE(split >= 1, "Fix your test"); + + int ret; + size_t left = input_len; + size_t part = input_len / split; + size_t written; + + BOOST_REQUIRE_MESSAGE(part >= 1, "Fix your test"); + output_len = 0; + + for (;;) { + ret = fun(ctx, input, part, output, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + output_len += written; + output += written; + input += part; + left -= part; + + if (left == 0) + break; + + if (left < part) + part = left; + } +} diff --git a/tests/common.h b/tests/common.h new file mode 100644 index 0000000..6c661e3 --- /dev/null +++ b/tests/common.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Pawelczyk + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file common.h + * @author Lukasz Pawelczyk + * @brief Common headers for YACA unit tests + */ + +#ifndef COMMON_H +#define COMMON_H + +#include + +#include +#include +#include "../src/debug.h" + + +constexpr size_t INPUT_DATA_SIZE = 4096; +constexpr char INPUT_DATA[INPUT_DATA_SIZE] = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus congue semper ipsum, ac convallis magna rhoncus sit amet. Donec pellentesque maximus convallis. Mauris ut egestas sem. Maecenas efficitur suscipit auctor. Nunc malesuada laoreet porttitor. Donec gravida tortor nisi, in mattis lectus porta ut. Integer vehicula eros et tellus placerat, nec fermentum justo aliquet.\ +Maecenas metus massa, ultrices et ultricies sed, imperdiet nec dolor. Nam eget massa eros. Proin vitae laoreet metus, at scelerisque massa. Nullam convallis dolor id nisl iaculis, a gravida risus pretium. Proin non nunc eget nibh fermentum dignissim. Nullam tristique, odio eget rutrum sagittis, tortor purus cursus nunc, nec iaculis quam nunc ac metus. Cras ut tortor a eros porta vehicula non at lectus. Aliquam volutpat quis nisi ut mattis. Curabitur semper vehicula ultrices. Aenean cursus laoreet venenatis. Aenean vulputate, nisl id facilisis fringilla, neque velit posuere libero, et viverra tortor felis vitae urna. Sed in congue nunc. Fusce molestie tempor pharetra. Cras sodales pulvinar nunc non sollicitudin.\ +Maecenas vehicula metus ac tristique ultricies. Suspendisse potenti. Pellentesque suscipit egestas augue, sed dictum orci. Pellentesque eu lorem ultricies, vestibulum est in, bibendum turpis. Proin placerat tincidunt metus, eget volutpat dolor. Pellentesque varius leo eget velit lobortis, sit amet congue orci bibendum. Aliquam vitae posuere lorem. Donec sed convallis diam. Quisque aliquam interdum purus, eu ornare ex ullamcorper iaculis. In sit amet nisl eu nisl ultricies dapibus. Aenean finibus efficitur elit ut sodales. Nam sit amet auctor sem, eu iaculis nunc. Vivamus mattis arcu a viverra faucibus. In dignissim, nisi sit amet consectetur tempus, lorem dui fringilla augue, sit amet lacinia lectus sapien efficitur odio.\ +Nullam et egestas enim. Nam sit amet mi malesuada, dapibus felis quis, viverra mauris. Ut quis enim eu neque porta vehicula. Etiam ullamcorper vitae turpis vehicula blandit. Maecenas blandit tristique semper. Aliquam at sagittis enim. Donec quis molestie urna. Duis ut urna blandit, pellentesque magna ultrices, dignissim mi. Morbi fermentum ex massa, ut facilisis est tincidunt vel. Nam sed erat in lacus molestie mattis quis ut leo. Phasellus tempus elit urna, eget sagittis purus volutpat sed. Suspendisse aliquam, sem vel gravida lobortis, tortor orci ornare nisi, sed mollis ligula sem nec risus. In a ex nibh. Praesent odio est, molestie sed vestibulum id, varius sit amet lectus. Donec vel diam efficitur, tristique ligula a, aliquet felis. Nullam sit amet neque tellus.\ +Phasellus aliquet non libero non aliquet. Aliquam efficitur ultrices tortor vitae lobortis. Pellentesque sed dolor quis nisl faucibus eleifend vitae ultrices est. Integer et libero quis nisl sollicitudin volutpat sit amet a quam. Vivamus commodo dolor augue, volutpat dapibus odio dapibus et. Nulla sed congue nisl. Duis nunc sem, condimentum nec neque ac, blandit blandit quam. Integer tincidunt ipsum nec risus viverra mollis. In porta porttitor mattis. Nulla ac eleifend nibh. Vivamus suscipit at nunc ac interdum. In fermentum fringilla odio.\ +Sed nec erat eget mauris varius pulvinar. Ut fermentum ante non erat elementum, vitae tempor velit blandit. Curabitur turpis tellus, sodales sit amet mattis nec, volutpat ac magna. Nulla quam orci, rutrum sit amet imperdiet ut, iaculis in nisl. Donec semper vitae tellus nec bibendum. Nam pharetra hendrerit sapien quis rutrum. Morbi tincidunt justo ut sodales ullamcorper. Suspendisse eget pellentesque nulla, non placerat purus. Donec placerat id turpis in interdum. Curabitur lobortis risus et placerat commodo. Morbi pulvinar eros leo, scelerisque rutrum arcu pretium at. Quisque eget diam dui. Quisque bibendum luctus arcu quis semper. Nullam erat lacus, lacinia sit amet neque aliquam, lacinia maximus lorem.\ +Nunc ac purus vel sem laoreet interdum quis eget ligula. Aenean id nisl ut quam vehicula pretium sed sit amet urna. Aenean diam lorem, vehicula et sapien nec, pellentesque consectetur libero. Cras fringilla nibh eu libero nullam."; + +constexpr size_t IGNORE = static_cast(-1); + +#define DEFINE_INVALID(type, name) \ + constexpr type YACA_INVALID_##name = static_cast(-1) + +DEFINE_INVALID(yaca_error_e, ERROR); +DEFINE_INVALID(yaca_key_format_e, KEY_FORMAT); +DEFINE_INVALID(yaca_key_file_format_e, KEY_FILE_FORMAT); +DEFINE_INVALID(yaca_key_type_e, KEY_TYPE); +DEFINE_INVALID(yaca_key_bit_length_e, KEY_BIT_LENGTH); +DEFINE_INVALID(yaca_key_bit_length_ec_e, KEY_BIT_LENGTH_EC); +DEFINE_INVALID(yaca_key_bit_length_dh_rfc_e, KEY_BIT_LENGTH_DH_RFC); +DEFINE_INVALID(yaca_digest_algorithm_e, DIGEST_ALGORITHM); +DEFINE_INVALID(yaca_encrypt_algorithm_e, ENCRYPT_ALGORITHM); +DEFINE_INVALID(yaca_block_cipher_mode_e, BLOCK_CIPHER_MODE); +DEFINE_INVALID(yaca_property_e, PROPERTY); +DEFINE_INVALID(yaca_padding_e, PADDING); +DEFINE_INVALID(yaca_kdf_e, KDF); + + +struct DebugFixture { + DebugFixture(); + ~DebugFixture(); +}; + +struct InitFixture { + InitFixture(); + ~InitFixture(); +}; + +struct InitDebugFixture { + InitFixture init; + DebugFixture debug; +}; + +void generate_asymmetric_keys(yaca_key_type_e type_prv, size_t key_bit_len, + yaca_key_h *key_prv, + yaca_key_h *key_pub = NULL, yaca_key_h *key_params = NULL); + +size_t allocate_output(yaca_context_h ctx, size_t input_len, size_t split, char *&output); + +using update_fun_5_t = int(yaca_context_h ctx, const char *plaintext, size_t plaintext_len, + char *ciphertext, size_t *ciphertext_len); + +void call_update_loop(yaca_context_h ctx, const char *input, size_t input_len, + char *output, size_t &output_len, size_t split, + update_fun_5_t *fun); + +#endif /* COMMON_H */ diff --git a/tests/test_crypto.cpp b/tests/test_crypto.cpp new file mode 100644 index 0000000..2c16460 --- /dev/null +++ b/tests/test_crypto.cpp @@ -0,0 +1,334 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Pawelczyk + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file test_crypto.cpp + * @author Lukasz Pawelczyk + * @brief Base crypto API unit tests. + */ + +#include + +#include + +#include +#include + +#include "common.h" + + +namespace { + +const size_t DATA_SIZE = 10; + +bool is_mem_zero(const char* p, size_t size) +{ + for (size_t i = 0; i < size; ++i) + if (p[i] != '\0') + return false; + return true; +} + +} + +BOOST_AUTO_TEST_SUITE(TESTS_CRYPTO) + +BOOST_FIXTURE_TEST_CASE(T101__positive__init, DebugFixture) +{ + int ret; + + ret = yaca_initialize(); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_cleanup(); +} + +BOOST_FIXTURE_TEST_CASE(T102__negative__double_init, DebugFixture) +{ + int ret; + + ret = yaca_initialize(); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_initialize(); + BOOST_REQUIRE(ret == YACA_ERROR_INTERNAL); + + yaca_cleanup(); +} + +BOOST_FIXTURE_TEST_CASE(T103__negative__double_cleanup, DebugFixture) +{ + int ret; + + ret = yaca_initialize(); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_cleanup(); + + yaca_cleanup(); +} + +BOOST_FIXTURE_TEST_CASE(T104__positivie__malloc, InitDebugFixture) +{ + int ret; + char *alloc; + + ret = yaca_malloc(DATA_SIZE, (void**)&alloc); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + BOOST_REQUIRE(alloc != NULL); + + yaca_free(alloc); +} + +BOOST_FIXTURE_TEST_CASE(T105__negative__malloc, InitDebugFixture) +{ + int ret; + char *alloc; + + ret = yaca_malloc(0, (void**)&alloc); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_malloc(DATA_SIZE, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_malloc(0, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); +} + +BOOST_FIXTURE_TEST_CASE(T106__positive__zalloc, InitDebugFixture) +{ + int ret; + char *alloc; + + ret = yaca_zalloc(DATA_SIZE, (void**)&alloc); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + BOOST_REQUIRE(alloc != NULL); + + BOOST_REQUIRE(is_mem_zero(alloc, DATA_SIZE)); + + yaca_free(alloc); +} + +BOOST_FIXTURE_TEST_CASE(T107__negative__zalloc, InitDebugFixture) +{ + int ret; + char *alloc; + + ret = yaca_zalloc(0, (void**)&alloc); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_zalloc(DATA_SIZE, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_zalloc(0, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); +} + +BOOST_FIXTURE_TEST_CASE(T108__positive__realloc, InitDebugFixture) +{ + int ret; + char *alloc; + + ret = yaca_zalloc(DATA_SIZE, (void**)&alloc); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_realloc(DATA_SIZE * 2, (void**)&alloc); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + BOOST_REQUIRE(alloc != NULL); + + BOOST_REQUIRE(is_mem_zero(alloc, DATA_SIZE)); + + ret = yaca_realloc(DATA_SIZE / 2, (void**)&alloc); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + BOOST_REQUIRE(alloc != NULL); + + BOOST_REQUIRE(is_mem_zero(alloc, DATA_SIZE / 2)); + + yaca_free(alloc); + alloc = NULL; + + ret = yaca_realloc(DATA_SIZE, (void**)&alloc); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + BOOST_REQUIRE(alloc != NULL); + + yaca_free(alloc); +} + +BOOST_FIXTURE_TEST_CASE(T109__negative__realloc, InitDebugFixture) +{ + int ret; + char *alloc; + + ret = yaca_zalloc(DATA_SIZE, (void**)&alloc); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_realloc(0, (void**)&alloc); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + BOOST_REQUIRE(is_mem_zero(alloc, DATA_SIZE)); + + ret = yaca_realloc(DATA_SIZE, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_realloc(0, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_free(alloc); +} + +BOOST_FIXTURE_TEST_CASE(T110__positive__memcmp, InitDebugFixture) +{ + int ret; + char *alloc1, *alloc2; + + ret = yaca_memcmp(NULL, NULL, 0); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_zalloc(DATA_SIZE, (void**)&alloc1); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_zalloc(DATA_SIZE, (void**)&alloc2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_memcmp(alloc1, alloc2, DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_memcmp(alloc1, alloc2, 0); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_memcmp(NULL, alloc2, 0); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_memcmp(alloc1, NULL, 0); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + alloc1[9] = 'a'; + + ret = yaca_memcmp(alloc1, alloc2, DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_DATA_MISMATCH); + + ret = yaca_memcmp(alloc1, alloc2, 9); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + alloc2[0] = 'a'; + + ret = yaca_memcmp(alloc1, alloc2, 9); + BOOST_REQUIRE(ret == YACA_ERROR_DATA_MISMATCH); + + ret = yaca_memcmp(alloc1, alloc1, DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_memcmp(alloc2, alloc2, DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_free(alloc1); + yaca_free(alloc2); +} + +BOOST_FIXTURE_TEST_CASE(T111__negative__memcmp, InitDebugFixture) +{ + int ret; + char *alloc; + + ret = yaca_malloc(DATA_SIZE, (void**)&alloc); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_memcmp(alloc, NULL, DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_memcmp(NULL, alloc, DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_free(alloc); +} + +BOOST_FIXTURE_TEST_CASE(T112__positive__yaca_randomize_bytes, InitDebugFixture) +{ + int ret; + char *alloc1, *alloc2; + + ret = yaca_zalloc(DATA_SIZE, (void**)&alloc1); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_zalloc(DATA_SIZE, (void**)&alloc2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_randomize_bytes(alloc1, DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + BOOST_REQUIRE(!is_mem_zero(alloc1, DATA_SIZE)); + + ret = yaca_memcmp(alloc1, alloc2, DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_DATA_MISMATCH); + + ret = yaca_randomize_bytes(alloc2, DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + BOOST_REQUIRE(!is_mem_zero(alloc2, DATA_SIZE)); + + ret = yaca_memcmp(alloc1, alloc2, DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_DATA_MISMATCH); + + yaca_free(alloc1); + yaca_free(alloc2); +} + +BOOST_FIXTURE_TEST_CASE(T113__negative__yaca_randomize_bytes, InitDebugFixture) +{ + int ret; + char *alloc; + + ret = yaca_malloc(DATA_SIZE, (void**)&alloc); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_randomize_bytes(alloc, 0); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_randomize_bytes(NULL, DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + +} + +BOOST_FIXTURE_TEST_CASE(T114__negative__yaca_context, InitDebugFixture) +{ + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_padding_e *get, set = YACA_PADDING_NONE; + size_t output, input = sizeof(yaca_padding_e); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, (void*)&set, input); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_get_property(ctx, YACA_PROPERTY_PADDING, (void**)&get, &output); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_get_output_length(ctx, 0, &output); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); +} + +BOOST_FIXTURE_TEST_CASE(T115__positive__openssl_rand, InitDebugFixture) +{ + static const size_t LEN = 256; + int ret; + unsigned char rand_bytes[LEN] = {}; + + ret = RAND_status(); + BOOST_REQUIRE(ret == 1); + + BOOST_REQUIRE(is_mem_zero((const char *)rand_bytes, LEN)); + ret = RAND_bytes(rand_bytes, LEN); + BOOST_REQUIRE(ret == 1); + BOOST_REQUIRE(!is_mem_zero((const char *)rand_bytes, LEN)); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/test_debug.cpp b/tests/test_debug.cpp new file mode 100644 index 0000000..3786abd --- /dev/null +++ b/tests/test_debug.cpp @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Pawelczyk + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file test_debug.cpp + * @author Lukasz Pawelczyk + * @brief Debug internal API unit tests. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include "../src/debug.h" +#include "common.h" + + +namespace { + +int error_cb_called = 0; + +/* Has to be the same as BUF_SIZE in error_dump */ +const size_t BUF_SIZE = 512; +/* Has to be the same as ELLIPSIS in error_dump */ +const char ELLIPSIS[] = "...\n"; + +char last_buf[BUF_SIZE] = {}; + +void debug_error_cb(const char *buf) +{ + ++error_cb_called; + + BOOST_REQUIRE(strlen(buf) < BUF_SIZE); + memcpy(last_buf, buf, BUF_SIZE); +} + +struct CallbackCleanup +{ + CallbackCleanup() + { + error_cb_called = 0; + } + ~CallbackCleanup() + { + yaca_debug_set_error_cb(NULL); + } +}; + +} + +BOOST_AUTO_TEST_SUITE(TESTS_DEBUG) + +BOOST_AUTO_TEST_CASE(T001__neutral__translate_error) +{ + struct error_args { + yaca_error_e err; + std::string msg; + }; + + const std::vector eargs = { + {YACA_INVALID_ERROR, "Error not defined"}, + {YACA_ERROR_NONE, "YACA_ERROR_NONE"}, + {YACA_ERROR_INVALID_PARAMETER, "YACA_ERROR_INVALID_PARAMETER"}, + {YACA_ERROR_OUT_OF_MEMORY, "YACA_ERROR_OUT_OF_MEMORY"}, + {YACA_ERROR_INTERNAL, "YACA_ERROR_INTERNAL"}, + {YACA_ERROR_DATA_MISMATCH, "YACA_ERROR_DATA_MISMATCH"}, + {YACA_ERROR_INVALID_PASSWORD, "YACA_ERROR_INVALID_PASSWORD"}, + }; + + for (const auto &ea: eargs) { + std::string ret = yaca_debug_translate_error(ea.err); + BOOST_REQUIRE(ret == ea.msg); + } +} + +BOOST_FIXTURE_TEST_CASE(T002__neutral__debug_set_error_cb, CallbackCleanup) +{ + ERROR_DUMP(YACA_ERROR_INTERNAL); + BOOST_REQUIRE(error_cb_called == 0); + + yaca_debug_set_error_cb(&debug_error_cb); + ERROR_DUMP(YACA_ERROR_INTERNAL); + BOOST_REQUIRE(error_cb_called == 1); + + ERROR_DUMP(YACA_ERROR_INTERNAL); + BOOST_REQUIRE(error_cb_called == 2); + + yaca_debug_set_error_cb(NULL); + ERROR_DUMP(YACA_ERROR_INTERNAL); + ERROR_DUMP(YACA_ERROR_INTERNAL); + BOOST_REQUIRE(error_cb_called == 2); +} + +BOOST_FIXTURE_TEST_CASE(T003__neutral__error_dump, CallbackCleanup) +{ + yaca_debug_set_error_cb(&debug_error_cb); + + /* I won't check the string that's been generated. It's too + * volatile. Some regexp can be implemented at most. */ + PEMerr(PEM_F_LOAD_IV, PEM_R_READ_KEY); + ERROR_DUMP(YACA_ERROR_INTERNAL); + BOOST_REQUIRE(error_cb_called == 1); + RSAerr(RSA_F_RSA_VERIFY, RSA_R_DATA_TOO_LARGE); + ERROR_DUMP(-1 * YACA_ERROR_INTERNAL); + BOOST_REQUIRE(error_cb_called == 2); + + /* The check that makes sense though is ellipsis. Also it'll + * trigger the ellipsis code so it's at least a crash check. + * No, those errors don't have to make any sense. */ + RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_KEY_SIZE_TOO_SMALL); + RSAerr(RSA_F_RSA_SIGN, RSA_R_MODULUS_TOO_LARGE); + DSAerr(DSA_F_PKEY_DSA_KEYGEN, DSA_R_PARAMETER_ENCODING_ERROR); + DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_MODULUS_TOO_LARGE); + PEMerr(PEM_F_PEM_ASN1_WRITE, PEM_R_BAD_PASSWORD_READ); + PEMerr(PEM_F_PEM_READ_DHPARAMS, PEM_R_UNSUPPORTED_CIPHER); + PEMerr(PEM_F_PEM_READ_BIO_EX, PEM_R_ERROR_CONVERTING_PRIVATE_KEY); + RSAerr(RSA_F_ENCODE_PKCS1, RSA_R_VALUE_MISSING); + ERROR_DUMP(YACA_ERROR_INTERNAL); + BOOST_REQUIRE(error_cb_called == 3); + + std::string ret(last_buf); + std::string ellipsis = ret.substr(ret.size() - strlen(ELLIPSIS)); + BOOST_REQUIRE(ellipsis == ELLIPSIS); +} + +BOOST_FIXTURE_TEST_CASE(T004__neutral__error_handle, CallbackCleanup) +{ + struct error_args { + long err1; + long err2; + yaca_error_e expected; + int cb_called; + }; + + const std::vector eargs = { + {-1, -1, YACA_ERROR_INTERNAL, 0}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN), + -1, YACA_ERROR_INVALID_PARAMETER, 0}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_CTRL, RSA_R_KEY_SIZE_TOO_SMALL), + -1, YACA_ERROR_INVALID_PARAMETER, 0}, + {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_GET_OBJECT, ASN1_R_TOO_LONG), + ERR_PACK(ERR_LIB_RSA, RSA_F_OLD_RSA_PRIV_DECODE, ERR_R_RSA_LIB), + YACA_ERROR_INVALID_PASSWORD, 0}, + {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_GET_OBJECT, ASN1_R_HEADER_TOO_LONG), + ERR_PACK(ERR_LIB_RSA, RSA_F_OLD_RSA_PRIV_DECODE, RSA_R_DIGEST_NOT_ALLOWED), + YACA_ERROR_INVALID_PARAMETER, 0}, + {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_READ_BIO_PRIVATEKEY, PEM_R_BAD_PASSWORD_READ), + -1, YACA_ERROR_INVALID_PASSWORD, 0}, + {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_DO_HEADER, PEM_R_BAD_DECRYPT), + -1, YACA_ERROR_INVALID_PASSWORD, 0}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_CHECK_PADDING_MD, PEM_R_BAD_DECRYPT), + -1, YACA_ERROR_INVALID_PARAMETER, 0}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, PEM_R_BAD_DECRYPT), + -1, YACA_ERROR_INVALID_PARAMETER, 0}, + {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_SIGN, ERR_R_MALLOC_FAILURE), + -1, YACA_ERROR_OUT_OF_MEMORY, 0}, + {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_SIGN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED), + -1, YACA_ERROR_INVALID_PARAMETER, 0}, + {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_SIGN, ERR_R_PASSED_NULL_PARAMETER), + -1, YACA_ERROR_INVALID_PARAMETER, 0}, + {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_SIGN, ERR_R_INTERNAL_ERROR), + -1, YACA_ERROR_INTERNAL, 0}, + {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_SIGN, ERR_R_DISABLED), + -1, YACA_ERROR_INTERNAL, 0}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_SETUP_TBUF, RSA_R_BAD_SIGNATURE), + -1, YACA_ERROR_INTERNAL, 1}, + {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_NEW_METHOD, DSA_R_BN_ERROR), + -1, YACA_ERROR_INTERNAL, 1}, + {ERR_PACK(ERR_LIB_EC, EC_F_BN_TO_FELEM, EC_R_SLOT_FULL), + -1, YACA_ERROR_INTERNAL, 1}, + }; + + yaca_debug_set_error_cb(&debug_error_cb); + + for (const auto &ea: eargs) { + error_cb_called = 0; + + if (ea.err1 != -1) { + ERR_PUT_error(ERR_GET_LIB(ea.err1), ERR_GET_FUNC(ea.err1), + ERR_GET_REASON(ea.err1), OPENSSL_FILE, OPENSSL_LINE); + } + if (ea.err2 != -1) { + ERR_PUT_error(ERR_GET_LIB(ea.err2), ERR_GET_FUNC(ea.err2), + ERR_GET_REASON(ea.err2), OPENSSL_FILE, OPENSSL_LINE); + } + + int ret = ERROR_HANDLE(); + + BOOST_REQUIRE(ret == ea.expected); + BOOST_REQUIRE(error_cb_called == ea.cb_called); + } + +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/test_digest.cpp b/tests/test_digest.cpp new file mode 100644 index 0000000..c6b63c9 --- /dev/null +++ b/tests/test_digest.cpp @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Pawelczyk + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file test_digest.cpp + * @author Lukasz Pawelczyk + * @brief Digest API unit tests. + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "common.h" + + +BOOST_AUTO_TEST_SUITE(TESTS_DIGEST) + +BOOST_FIXTURE_TEST_CASE(T501__positive__yaca_digest, InitDebugFixture) +{ + struct digest_args { + yaca_digest_algorithm_e algo = YACA_DIGEST_SHA256; + size_t expected; + size_t split; + }; + + const std::vector dargs = { + {yaca_digest_algorithm_e::YACA_DIGEST_MD5, 16, 5}, + {yaca_digest_algorithm_e::YACA_DIGEST_SHA1, 20, 15}, + {yaca_digest_algorithm_e::YACA_DIGEST_SHA224, 28, 9}, + {yaca_digest_algorithm_e::YACA_DIGEST_SHA256, 32, 7}, + {yaca_digest_algorithm_e::YACA_DIGEST_SHA384, 48, 35}, + {yaca_digest_algorithm_e::YACA_DIGEST_SHA512, 64, 11} + }; + + for (const auto &da: dargs) { + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + char *digest = NULL; + size_t digest_len; + + ret = yaca_digest_initialize(&ctx, da.algo); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + const char *input = INPUT_DATA; + size_t left = INPUT_DATA_SIZE; + size_t todo = INPUT_DATA_SIZE / da.split; + BOOST_REQUIRE_MESSAGE(todo > 0, "Fix your test"); + + for (;;) { + ret = yaca_digest_update(ctx, input, todo); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + input += todo; + left -= todo; + + if (left == 0) + break; + + if (left < todo) + todo = left; + } + + ret = yaca_context_get_output_length(ctx, 0, &digest_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_malloc(digest_len, (void**)&digest); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + BOOST_REQUIRE(digest != NULL); + + ret = yaca_digest_finalize(ctx, digest, &digest_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + BOOST_REQUIRE(digest_len == da.expected); + + yaca_context_destroy(ctx); + yaca_free(digest); + } +} + +BOOST_FIXTURE_TEST_CASE(T502__negative__yaca_digest, InitDebugFixture) +{ + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_context_h ctx_encrypt = YACA_CONTEXT_NULL; + yaca_key_h key_sym = YACA_KEY_NULL; + char *digest = NULL; + size_t digest_len; + yaca_padding_e pad = YACA_PADDING_PKCS1; + size_t bit_len = 256; + + ret = yaca_digest_initialize(NULL, YACA_DIGEST_MD5); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_digest_initialize(&ctx, YACA_INVALID_DIGEST_ALGORITHM); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_digest_initialize(&ctx, YACA_DIGEST_MD5); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_256BIT, &key_sym); + ret = yaca_encrypt_initialize(&ctx_encrypt, YACA_ENCRYPT_AES, + YACA_BCM_ECB, key_sym, YACA_KEY_NULL); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad, sizeof(yaca_padding_e)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_RC2_EFFECTIVE_KEY_BITS, + &bit_len, sizeof(size_t)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_digest_update(NULL, INPUT_DATA, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_digest_update(ctx_encrypt, INPUT_DATA, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_digest_update(ctx, NULL, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_digest_update(ctx, INPUT_DATA, 0); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_digest_update(ctx, INPUT_DATA, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_get_output_length(YACA_CONTEXT_NULL, 0, &digest_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_get_output_length(ctx, 10, &digest_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_get_output_length(ctx, 0, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_get_output_length(ctx, 0, &digest_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_malloc(digest_len, (void**)&digest); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_digest_finalize(YACA_CONTEXT_NULL, digest, &digest_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_digest_finalize(ctx_encrypt, digest, &digest_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_digest_finalize(ctx, NULL, &digest_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_digest_finalize(ctx, digest, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_digest_finalize(ctx, digest, &digest_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_digest_update(ctx, INPUT_DATA, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_digest_finalize(ctx, digest, &digest_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + yaca_context_destroy(ctx_encrypt); + yaca_key_destroy(key_sym); + yaca_free(digest); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/test_encrypt.cpp b/tests/test_encrypt.cpp new file mode 100644 index 0000000..92565a6 --- /dev/null +++ b/tests/test_encrypt.cpp @@ -0,0 +1,2402 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Pawelczyk + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file test_encrypt.cpp + * @author Lukasz Pawelczyk + * @brief Encrypt API unit tests. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "common.h" + + +namespace { + +yaca_key_h generate_iv(yaca_encrypt_algorithm_e algo, yaca_block_cipher_mode_e bcm, + size_t key_bit_len, size_t iv_bit_len = IGNORE) +{ + int ret; + yaca_key_h iv = YACA_KEY_NULL; + + if (iv_bit_len == IGNORE) { + ret = yaca_encrypt_get_iv_bit_length(algo, bcm, key_bit_len, &iv_bit_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + if (iv_bit_len > 0) { + ret = yaca_key_generate(YACA_KEY_TYPE_IV, iv_bit_len, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + return iv; +} + +} // namespace + + +BOOST_AUTO_TEST_SUITE(TESTS_ENCRYPT) + +BOOST_FIXTURE_TEST_CASE(T601__positive__get_iv_bit_length, InitDebugFixture) +{ + struct iv_args { + yaca_encrypt_algorithm_e algo; + yaca_block_cipher_mode_e bcm; + size_t key_bit_len; + size_t expected_iv_bit_len; + }; + + const std::vector iargs = { + {YACA_ENCRYPT_AES, YACA_BCM_CBC, 128, 128}, + {YACA_ENCRYPT_AES, YACA_BCM_CCM, 128, 96}, + {YACA_ENCRYPT_AES, YACA_BCM_CFB, 128, 128}, + {YACA_ENCRYPT_AES, YACA_BCM_CFB1, 128, 128}, + {YACA_ENCRYPT_AES, YACA_BCM_CFB8, 128, 128}, + {YACA_ENCRYPT_AES, YACA_BCM_CTR, 128, 128}, + {YACA_ENCRYPT_AES, YACA_BCM_ECB, 128, 0}, + {YACA_ENCRYPT_AES, YACA_BCM_GCM, 128, 96}, + {YACA_ENCRYPT_AES, YACA_BCM_OFB, 128, 128}, + {YACA_ENCRYPT_AES, YACA_BCM_WRAP, 128, 64}, + + {YACA_ENCRYPT_AES, YACA_BCM_CBC, 192, 128}, + {YACA_ENCRYPT_AES, YACA_BCM_CCM, 192, 96}, + {YACA_ENCRYPT_AES, YACA_BCM_CFB, 192, 128}, + {YACA_ENCRYPT_AES, YACA_BCM_CFB1, 192, 128}, + {YACA_ENCRYPT_AES, YACA_BCM_CFB8, 192, 128}, + {YACA_ENCRYPT_AES, YACA_BCM_CTR, 192, 128}, + {YACA_ENCRYPT_AES, YACA_BCM_ECB, 192, 0}, + {YACA_ENCRYPT_AES, YACA_BCM_GCM, 192, 96}, + {YACA_ENCRYPT_AES, YACA_BCM_OFB, 192, 128}, + {YACA_ENCRYPT_AES, YACA_BCM_WRAP, 192, 64}, + + {YACA_ENCRYPT_AES, YACA_BCM_CBC, 256, 128}, + {YACA_ENCRYPT_AES, YACA_BCM_CCM, 256, 96}, + {YACA_ENCRYPT_AES, YACA_BCM_CFB, 256, 128}, + {YACA_ENCRYPT_AES, YACA_BCM_CFB1, 256, 128}, + {YACA_ENCRYPT_AES, YACA_BCM_CFB8, 256, 128}, + {YACA_ENCRYPT_AES, YACA_BCM_CTR, 256, 128}, + {YACA_ENCRYPT_AES, YACA_BCM_ECB, 256, 0}, + {YACA_ENCRYPT_AES, YACA_BCM_GCM, 256, 96}, + {YACA_ENCRYPT_AES, YACA_BCM_OFB, 256, 128}, + {YACA_ENCRYPT_AES, YACA_BCM_WRAP, 256, 64}, + + {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_CBC, 64, 64}, + {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_CFB, 64, 64}, + {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_CFB1, 64, 64}, + {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_CFB8, 64, 64}, + {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_ECB, 64, 0}, + {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_OFB, 64, 64}, + + {YACA_ENCRYPT_UNSAFE_3DES_2TDEA, YACA_BCM_CBC, 128, 64}, + {YACA_ENCRYPT_UNSAFE_3DES_2TDEA, YACA_BCM_CFB, 128, 64}, + {YACA_ENCRYPT_UNSAFE_3DES_2TDEA, YACA_BCM_ECB, 128, 0}, + {YACA_ENCRYPT_UNSAFE_3DES_2TDEA, YACA_BCM_OFB, 128, 64}, + + {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_CBC, 192, 64}, + {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_CFB, 192, 64}, + {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_CFB1, 192, 64}, + {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_CFB8, 192, 64}, + {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_ECB, 192, 0}, + {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_OFB, 192, 64}, + {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_WRAP, 192, 0}, + + {YACA_ENCRYPT_UNSAFE_RC2, YACA_BCM_CBC, 192, 64}, + {YACA_ENCRYPT_UNSAFE_RC2, YACA_BCM_CFB, 192, 64}, + {YACA_ENCRYPT_UNSAFE_RC2, YACA_BCM_ECB, 192, 0}, + {YACA_ENCRYPT_UNSAFE_RC2, YACA_BCM_OFB, 192, 64}, + + {YACA_ENCRYPT_UNSAFE_RC4, YACA_BCM_NONE, 256, 0}, + + {YACA_ENCRYPT_CAST5, YACA_BCM_CBC, 128, 64}, + {YACA_ENCRYPT_CAST5, YACA_BCM_CFB, 128, 64}, + {YACA_ENCRYPT_CAST5, YACA_BCM_ECB, 128, 0}, + {YACA_ENCRYPT_CAST5, YACA_BCM_OFB, 128, 64}, + }; + + for (const auto &ia: iargs) { + int ret; + size_t iv_bit_len; + + ret = yaca_encrypt_get_iv_bit_length(ia.algo, ia.bcm, ia.key_bit_len, &iv_bit_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + BOOST_REQUIRE(iv_bit_len == ia.expected_iv_bit_len); + } +} + +BOOST_FIXTURE_TEST_CASE(T602__negative__get_iv_bit_length, InitDebugFixture) +{ + int ret; + size_t iv_bit_len; + + ret = yaca_encrypt_get_iv_bit_length(YACA_INVALID_ENCRYPT_ALGORITHM, YACA_BCM_CBC, + YACA_KEY_LENGTH_256BIT, &iv_bit_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_get_iv_bit_length(YACA_ENCRYPT_AES, YACA_INVALID_BLOCK_CIPHER_MODE, + YACA_KEY_LENGTH_256BIT, &iv_bit_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_get_iv_bit_length(YACA_ENCRYPT_AES, YACA_BCM_CBC, + 0, &iv_bit_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_get_iv_bit_length(YACA_ENCRYPT_AES, YACA_BCM_CBC, + 1, &iv_bit_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_get_iv_bit_length(YACA_ENCRYPT_AES, YACA_BCM_CBC, + 8, &iv_bit_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_get_iv_bit_length(YACA_ENCRYPT_AES, YACA_BCM_CBC, + YACA_KEY_LENGTH_256BIT, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_get_iv_bit_length(YACA_ENCRYPT_AES, YACA_BCM_CBC, + YACA_KEY_LENGTH_UNSAFE_64BIT, &iv_bit_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_get_iv_bit_length(YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_CBC, + YACA_KEY_LENGTH_192BIT, &iv_bit_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_get_iv_bit_length(YACA_ENCRYPT_UNSAFE_3DES_2TDEA, YACA_BCM_CBC, + YACA_KEY_LENGTH_192BIT, &iv_bit_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_get_iv_bit_length(YACA_ENCRYPT_UNSAFE_RC2, YACA_BCM_CBC, + YACA_KEY_LENGTH_2048BIT, &iv_bit_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_get_iv_bit_length(YACA_ENCRYPT_UNSAFE_RC4, YACA_BCM_NONE, + YACA_KEY_LENGTH_4096BIT, &iv_bit_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_get_iv_bit_length(YACA_ENCRYPT_CAST5, YACA_BCM_CBC, + YACA_KEY_LENGTH_UNSAFE_8BIT, &iv_bit_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); +} + +BOOST_FIXTURE_TEST_CASE(T603__positive__encrypt_decrypt, InitDebugFixture) +{ + struct encrypt_args { + yaca_encrypt_algorithm_e algo; + yaca_block_cipher_mode_e bcm; + size_t key_bit_len; + yaca_padding_e padding; + size_t split; + }; + + const std::vector eargs = { + {YACA_ENCRYPT_AES, YACA_BCM_CBC, 128, YACA_INVALID_PADDING, 16}, + {YACA_ENCRYPT_AES, YACA_BCM_CBC, 128, YACA_PADDING_NONE, 8}, + {YACA_ENCRYPT_AES, YACA_BCM_CBC, 128, YACA_PADDING_PKCS7, 11}, + {YACA_ENCRYPT_AES, YACA_BCM_CFB, 128, YACA_INVALID_PADDING, 24}, + {YACA_ENCRYPT_AES, YACA_BCM_CFB1, 128, YACA_INVALID_PADDING, 13}, + {YACA_ENCRYPT_AES, YACA_BCM_CFB8, 128, YACA_INVALID_PADDING, 4}, + {YACA_ENCRYPT_AES, YACA_BCM_CTR, 128, YACA_INVALID_PADDING, 66}, + {YACA_ENCRYPT_AES, YACA_BCM_ECB, 128, YACA_INVALID_PADDING, 3}, + {YACA_ENCRYPT_AES, YACA_BCM_ECB, 128, YACA_PADDING_NONE, 11}, + {YACA_ENCRYPT_AES, YACA_BCM_ECB, 128, YACA_PADDING_PKCS7, 34}, + {YACA_ENCRYPT_AES, YACA_BCM_OFB, 128, YACA_INVALID_PADDING, 27}, + + {YACA_ENCRYPT_AES, YACA_BCM_CBC, 192, YACA_INVALID_PADDING, 9}, + {YACA_ENCRYPT_AES, YACA_BCM_CBC, 192, YACA_PADDING_NONE, 12}, + {YACA_ENCRYPT_AES, YACA_BCM_CBC, 192, YACA_PADDING_PKCS7, 11}, + {YACA_ENCRYPT_AES, YACA_BCM_CFB, 192, YACA_INVALID_PADDING, 31}, + {YACA_ENCRYPT_AES, YACA_BCM_CFB1, 192, YACA_INVALID_PADDING, 17}, + {YACA_ENCRYPT_AES, YACA_BCM_CFB8, 192, YACA_INVALID_PADDING, 2}, + {YACA_ENCRYPT_AES, YACA_BCM_CTR, 192, YACA_INVALID_PADDING, 1}, + {YACA_ENCRYPT_AES, YACA_BCM_ECB, 192, YACA_INVALID_PADDING, 24}, + {YACA_ENCRYPT_AES, YACA_BCM_ECB, 192, YACA_PADDING_NONE, 15}, + {YACA_ENCRYPT_AES, YACA_BCM_ECB, 192, YACA_PADDING_PKCS7, 33}, + {YACA_ENCRYPT_AES, YACA_BCM_OFB, 192, YACA_INVALID_PADDING, 44}, + + {YACA_ENCRYPT_AES, YACA_BCM_CBC, 256, YACA_INVALID_PADDING, 10}, + {YACA_ENCRYPT_AES, YACA_BCM_CBC, 256, YACA_PADDING_NONE, 11}, + {YACA_ENCRYPT_AES, YACA_BCM_CBC, 256, YACA_PADDING_PKCS7, 23}, + {YACA_ENCRYPT_AES, YACA_BCM_CFB, 256, YACA_INVALID_PADDING, 17}, + {YACA_ENCRYPT_AES, YACA_BCM_CFB1, 256, YACA_INVALID_PADDING, 23}, + {YACA_ENCRYPT_AES, YACA_BCM_CFB8, 256, YACA_INVALID_PADDING, 29}, + {YACA_ENCRYPT_AES, YACA_BCM_CTR, 256, YACA_INVALID_PADDING, 21}, + {YACA_ENCRYPT_AES, YACA_BCM_ECB, 256, YACA_INVALID_PADDING, 9}, + {YACA_ENCRYPT_AES, YACA_BCM_ECB, 256, YACA_PADDING_NONE, 3}, + {YACA_ENCRYPT_AES, YACA_BCM_ECB, 256, YACA_PADDING_PKCS7, 15}, + {YACA_ENCRYPT_AES, YACA_BCM_OFB, 256, YACA_INVALID_PADDING, 13}, + + {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_CBC, 64, YACA_INVALID_PADDING, 31}, + {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_CBC, 64, YACA_PADDING_NONE, 22}, + {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_CBC, 64, YACA_PADDING_PKCS7, 39}, + {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_CFB, 64, YACA_INVALID_PADDING, 24}, + {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_CFB1, 64, YACA_INVALID_PADDING, 11}, + {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_CFB8, 64, YACA_INVALID_PADDING, 22}, + {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_ECB, 64, YACA_INVALID_PADDING, 7}, + {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_ECB, 64, YACA_PADDING_NONE, 19}, + {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_ECB, 64, YACA_PADDING_PKCS7, 9}, + {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_OFB, 64, YACA_INVALID_PADDING, 2}, + + {YACA_ENCRYPT_UNSAFE_3DES_2TDEA, YACA_BCM_CBC, 128, YACA_INVALID_PADDING, 16}, + {YACA_ENCRYPT_UNSAFE_3DES_2TDEA, YACA_BCM_CBC, 128, YACA_PADDING_NONE, 25}, + {YACA_ENCRYPT_UNSAFE_3DES_2TDEA, YACA_BCM_CBC, 128, YACA_PADDING_PKCS7, 26}, + {YACA_ENCRYPT_UNSAFE_3DES_2TDEA, YACA_BCM_CFB, 128, YACA_INVALID_PADDING, 23}, + {YACA_ENCRYPT_UNSAFE_3DES_2TDEA, YACA_BCM_ECB, 128, YACA_INVALID_PADDING, 13}, + {YACA_ENCRYPT_UNSAFE_3DES_2TDEA, YACA_BCM_ECB, 128, YACA_PADDING_NONE, 10}, + {YACA_ENCRYPT_UNSAFE_3DES_2TDEA, YACA_BCM_ECB, 128, YACA_PADDING_PKCS7, 29}, + {YACA_ENCRYPT_UNSAFE_3DES_2TDEA, YACA_BCM_OFB, 128, YACA_INVALID_PADDING, 32}, + + {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_CBC, 192, YACA_INVALID_PADDING, 39}, + {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_CBC, 192, YACA_PADDING_NONE, 29}, + {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_CBC, 192, YACA_PADDING_PKCS7, 19}, + {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_CFB, 192, YACA_INVALID_PADDING, 9}, + {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_CFB1, 192, YACA_INVALID_PADDING, 44}, + {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_CFB8, 192, YACA_INVALID_PADDING, 33}, + {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_ECB, 192, YACA_INVALID_PADDING, 22}, + {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_ECB, 192, YACA_PADDING_NONE, 11}, + {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_ECB, 192, YACA_PADDING_PKCS7, 13}, + {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_OFB, 192, YACA_INVALID_PADDING, 1}, + + {YACA_ENCRYPT_UNSAFE_RC4, YACA_BCM_NONE, 256, YACA_INVALID_PADDING, 17}, + + {YACA_ENCRYPT_CAST5, YACA_BCM_CBC, 128, YACA_INVALID_PADDING, 3}, + {YACA_ENCRYPT_CAST5, YACA_BCM_CBC, 128, YACA_PADDING_NONE, 24}, + {YACA_ENCRYPT_CAST5, YACA_BCM_CBC, 128, YACA_PADDING_PKCS7, 21}, + {YACA_ENCRYPT_CAST5, YACA_BCM_CFB, 128, YACA_INVALID_PADDING, 19}, + {YACA_ENCRYPT_CAST5, YACA_BCM_ECB, 128, YACA_INVALID_PADDING, 7}, + {YACA_ENCRYPT_CAST5, YACA_BCM_ECB, 128, YACA_PADDING_NONE, 6}, + {YACA_ENCRYPT_CAST5, YACA_BCM_ECB, 128, YACA_PADDING_PKCS7, 18}, + {YACA_ENCRYPT_CAST5, YACA_BCM_OFB, 128, YACA_INVALID_PADDING, 2}, + }; + + for (const auto &ea: eargs) { + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key = YACA_KEY_NULL, iv = YACA_KEY_NULL; + + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len = 0, decrypted_len = 0; + + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, ea.key_bit_len, &key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + iv = generate_iv(ea.algo, ea.bcm, ea.key_bit_len); + + /* ENCRYPT */ + { + ret = yaca_encrypt_initialize(&ctx, ea.algo, ea.bcm, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + size_t total = allocate_output(ctx, INPUT_DATA_SIZE, ea.split, encrypted); + size_t written; + + call_update_loop(ctx, INPUT_DATA, INPUT_DATA_SIZE, + encrypted, encrypted_len, ea.split, + &yaca_encrypt_update); + + if (ea.padding != YACA_INVALID_PADDING) { + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, &ea.padding, + sizeof(yaca_padding_e)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + ret = yaca_encrypt_finalize(ctx, encrypted + encrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + encrypted_len += written; + + BOOST_REQUIRE(encrypted_len <= total); + ret = yaca_realloc(encrypted_len, (void **)&encrypted); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* DECRYPT */ + { + ret = yaca_decrypt_initialize(&ctx, ea.algo, ea.bcm, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + if (ea.padding != YACA_INVALID_PADDING) { + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, &ea.padding, + sizeof(yaca_padding_e)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + size_t total = allocate_output(ctx, encrypted_len, ea.split, decrypted); + size_t written; + + call_update_loop(ctx, encrypted, encrypted_len, + decrypted, decrypted_len, ea.split, + &yaca_decrypt_update); + + ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len += written; + + BOOST_REQUIRE(decrypted_len <= total); + ret = yaca_realloc(decrypted_len, (void **)&decrypted); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + BOOST_REQUIRE(decrypted_len == INPUT_DATA_SIZE); + ret = yaca_memcmp(INPUT_DATA, decrypted, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_key_destroy(key); + yaca_key_destroy(iv); + yaca_free(encrypted); + yaca_free(decrypted); + } +} + +BOOST_FIXTURE_TEST_CASE(T604__negative__encrypt_decrypt, InitDebugFixture) +{ + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL, ctx_digest = YACA_CONTEXT_NULL; + yaca_key_h key = YACA_KEY_NULL, iv = YACA_KEY_NULL; + yaca_key_h key2 = YACA_KEY_NULL, iv2 = YACA_KEY_NULL; + yaca_key_h key_rsa = YACA_KEY_NULL, iv_invalid = YACA_KEY_NULL; + yaca_padding_e pad_pkcs7 = YACA_PADDING_PKCS7; + yaca_padding_e pad_invalid = YACA_PADDING_X931; + yaca_padding_e *pad_get; + size_t key_bits_len = 128, pad_get_len; + + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len = 0, decrypted_len = 0; + + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_256BIT, &key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_256BIT, &key2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_generate(YACA_KEY_TYPE_IV, YACA_KEY_LENGTH_IV_128BIT, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_generate(YACA_KEY_TYPE_IV, YACA_KEY_LENGTH_IV_128BIT, &iv2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_generate(YACA_KEY_TYPE_IV, 32, &iv_invalid); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_generate(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_1024BIT, &key_rsa); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_digest_initialize(&ctx_digest, YACA_DIGEST_MD5); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + /* ENCRYPT */ + { + ret = yaca_encrypt_initialize(NULL, YACA_ENCRYPT_AES, YACA_BCM_CBC, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_initialize(&ctx, YACA_INVALID_ENCRYPT_ALGORITHM, YACA_BCM_CBC, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_INVALID_BLOCK_CIPHER_MODE, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CBC, YACA_KEY_NULL, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CBC, iv2, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CBC, key_rsa, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CBC, key, YACA_KEY_NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CBC, key, iv_invalid); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CBC, key, key_rsa); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_ECB, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_UNSAFE_RC4, YACA_BCM_CFB, key, YACA_KEY_NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_UNSAFE_RC4, YACA_BCM_NONE, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_CBC, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CBC, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_get_output_length(ctx, INPUT_DATA_SIZE, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + size_t total = allocate_output(ctx, INPUT_DATA_SIZE, 1, encrypted); + size_t written; + + ret = yaca_encrypt_update(YACA_CONTEXT_NULL, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_update(ctx_digest, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_update(ctx, NULL, INPUT_DATA_SIZE, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_update(ctx, INPUT_DATA, 0, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + encrypted_len = written; + + ret = yaca_context_set_property(ctx, YACA_INVALID_PROPERTY, + &pad_pkcs7, sizeof(yaca_padding_e)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad_pkcs7, 0); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad_pkcs7, 1); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_RC2_EFFECTIVE_KEY_BITS, + &key_bits_len, sizeof(size_t)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad_invalid, sizeof(yaca_padding_e)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad_pkcs7, sizeof(yaca_padding_e)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_get_property(ctx, YACA_INVALID_PROPERTY, + (void**)&pad_get, &pad_get_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_get_property(ctx, YACA_PROPERTY_PADDING, + NULL, &pad_get_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_get_property(ctx, YACA_PROPERTY_PADDING, + (void**)&pad_get, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_get_property(ctx, YACA_PROPERTY_PADDING, + (void**)&pad_get, &pad_get_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_finalize(YACA_CONTEXT_NULL, encrypted + encrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_finalize(ctx_digest, encrypted + encrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_finalize(ctx, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_finalize(ctx, encrypted + encrypted_len, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_finalize(ctx, encrypted + encrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + encrypted_len += written; + BOOST_REQUIRE(encrypted_len <= total); + ret = yaca_realloc(encrypted_len, (void **)&encrypted); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad_pkcs7, sizeof(yaca_padding_e)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_finalize(ctx, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* DECRYPT */ + { + ret = yaca_decrypt_initialize(NULL, YACA_ENCRYPT_AES, YACA_BCM_CBC, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_initialize(&ctx, YACA_INVALID_ENCRYPT_ALGORITHM, YACA_BCM_CBC, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_INVALID_BLOCK_CIPHER_MODE, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CBC, YACA_KEY_NULL, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CBC, iv2, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CBC, key, YACA_KEY_NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CBC, key, iv_invalid); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CBC, key, key_rsa); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_ECB, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_UNSAFE_RC4, YACA_BCM_CFB, key, YACA_KEY_NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_UNSAFE_RC4, YACA_BCM_NONE, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_CBC, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CBC, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_INVALID_PROPERTY, + &pad_pkcs7, sizeof(yaca_padding_e)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad_pkcs7, 0); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad_pkcs7, 1); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_RC2_EFFECTIVE_KEY_BITS, + &key_bits_len, sizeof(size_t)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad_invalid, sizeof(yaca_padding_e)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad_pkcs7, sizeof(yaca_padding_e)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_get_property(ctx, YACA_INVALID_PROPERTY, + (void**)&pad_get, &pad_get_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_get_property(ctx, YACA_PROPERTY_PADDING, + NULL, &pad_get_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_get_property(ctx, YACA_PROPERTY_PADDING, + (void**)&pad_get, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_get_property(ctx, YACA_PROPERTY_PADDING, + (void**)&pad_get, &pad_get_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_get_output_length(ctx, encrypted_len, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_decrypt_update(YACA_CONTEXT_NULL, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_update(ctx_digest, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_update(ctx, NULL, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_update(ctx, encrypted, 0, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len = written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad_pkcs7, sizeof(yaca_padding_e)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_finalize(YACA_CONTEXT_NULL, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_finalize(ctx_digest, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_finalize(ctx, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len += written; + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_finalize(ctx, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + /* DECRYPT, wrong BCM */ + { + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_ECB, key, YACA_KEY_NULL); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, &pad_pkcs7, + sizeof(yaca_padding_e)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len = written; + + ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + /* DECRYPT, wrong key */ + { + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CBC, key2, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, &pad_pkcs7, + sizeof(yaca_padding_e)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len = written; + + ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + /* DECRYPT, broken the end of ciphertext */ + { + encrypted[encrypted_len - 1] = ~encrypted[encrypted_len - 1]; + encrypted[encrypted_len - 2] = ~encrypted[encrypted_len - 2]; + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CBC, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, &pad_pkcs7, + sizeof(yaca_padding_e)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len = written; + + ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + yaca_context_destroy(ctx_digest); + yaca_key_destroy(key); + yaca_key_destroy(key2); + yaca_key_destroy(iv); + yaca_key_destroy(iv2); + yaca_key_destroy(key_rsa); + yaca_free(encrypted); +} + +BOOST_FIXTURE_TEST_CASE(T605__positive__encrypt_decrypt_wrap, InitDebugFixture) +{ + struct encrypt_args { + yaca_encrypt_algorithm_e algo; + size_t key_bit_len; + size_t key_material_len; + }; + + const std::vector eargs = { + {YACA_ENCRYPT_AES, 128, 192 / 8}, + {YACA_ENCRYPT_AES, 192, 256 / 8}, + {YACA_ENCRYPT_AES, 256, 128 / 8}, + {YACA_ENCRYPT_3DES_3TDEA, 192, 128 / 8}, + {YACA_ENCRYPT_3DES_3TDEA, 192, 192 / 8}, + }; + + for (const auto &ea: eargs) { + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key = YACA_KEY_NULL, iv = YACA_KEY_NULL; + char *key_material = NULL; + + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len, decrypted_len; + + ret = yaca_zalloc(ea.key_material_len, (void**)&key_material); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_randomize_bytes(key_material, ea.key_material_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, ea.key_bit_len, &key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + iv = generate_iv(ea.algo, YACA_BCM_WRAP, ea.key_bit_len); + + /* ENCRYPT */ + { + ret = yaca_encrypt_initialize(&ctx, ea.algo, YACA_BCM_WRAP, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + size_t total = allocate_output(ctx, ea.key_material_len, 1, encrypted); + size_t written; + + ret = yaca_encrypt_update(ctx, key_material, ea.key_material_len, + encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + encrypted_len = written; + + ret = yaca_encrypt_finalize(ctx, encrypted + encrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + encrypted_len += written; + + BOOST_REQUIRE(encrypted_len <= total); + ret = yaca_realloc(encrypted_len, (void **)&encrypted); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* DECRYPT */ + { + ret = yaca_decrypt_initialize(&ctx, ea.algo, YACA_BCM_WRAP, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + size_t total = allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len = written; + + ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len += written; + + BOOST_REQUIRE(decrypted_len <= total); + ret = yaca_realloc(decrypted_len, (void **)&decrypted); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + BOOST_REQUIRE(decrypted_len == ea.key_material_len); + ret = yaca_memcmp(key_material, decrypted, decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_key_destroy(key); + yaca_key_destroy(iv); + yaca_free(key_material); + yaca_free(encrypted); + yaca_free(decrypted); + } +} + +BOOST_FIXTURE_TEST_CASE(T606__negative__encrypt_decrypt_wrap, InitDebugFixture) +{ + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key_sym = YACA_KEY_NULL, iv = YACA_KEY_NULL; + yaca_key_h key_des1 = YACA_KEY_NULL, key_des2 = YACA_KEY_NULL; + char *key_material_64 = NULL, *key_material_192 = NULL, *key_material_256 = NULL; + + size_t len64 = 64 / 8, len192 = 192 / 8, len256 = 256 / 8; + + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len, decrypted_len; + + ret = yaca_zalloc(len64, (void**)&key_material_64); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_randomize_bytes(key_material_64, len64); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_zalloc(len192, (void**)&key_material_192); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_randomize_bytes(key_material_192, len192); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_zalloc(len256, (void**)&key_material_256); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_randomize_bytes(key_material_256, len256); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_UNSAFE_128BIT, &key_sym); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_generate(YACA_KEY_TYPE_DES, YACA_KEY_LENGTH_UNSAFE_64BIT, &key_des1); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_generate(YACA_KEY_TYPE_DES, YACA_KEY_LENGTH_192BIT, &key_des2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_key_generate(YACA_KEY_TYPE_IV, YACA_KEY_LENGTH_IV_64BIT, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + /* ENCRYPT AES */ + { + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_UNSAFE_DES, + YACA_BCM_WRAP, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_CAST5, + YACA_BCM_WRAP, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_AES, + YACA_BCM_WRAP, key_des1, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_AES, + YACA_BCM_WRAP, key_sym, YACA_KEY_NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_AES, + YACA_BCM_WRAP, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + size_t total = allocate_output(ctx, len192, 1, encrypted); + size_t written; + + ret = yaca_encrypt_update(ctx, key_material_64, len64, + encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_update(ctx, key_material_192, len192, + encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + encrypted_len = written; + + ret = yaca_encrypt_update(ctx, key_material_192, len192, + encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_finalize(ctx, encrypted + encrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + encrypted_len += written; + BOOST_REQUIRE(encrypted_len <= total); + ret = yaca_realloc(encrypted_len, (void **)&encrypted); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_encrypt_update(ctx, key_material_192, len192, + encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_finalize(ctx, encrypted + encrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* DECRYPT AES */ + { + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_UNSAFE_DES, + YACA_BCM_WRAP, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_CAST5, + YACA_BCM_WRAP, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, + YACA_BCM_WRAP, key_des1, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, + YACA_BCM_WRAP, key_sym, YACA_KEY_NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_WRAP, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len - 1, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len = written; + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len += written; + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + /* ENCRYPT 3DES */ + { + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_3DES_3TDEA, + YACA_BCM_WRAP, key_sym, YACA_KEY_NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_3DES_3TDEA, + YACA_BCM_WRAP, key_des1, YACA_KEY_NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_3DES_3TDEA, + YACA_BCM_WRAP, key_des2, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_3DES_3TDEA, + YACA_BCM_WRAP, key_des2, YACA_KEY_NULL); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + size_t total = allocate_output(ctx, len192, 1, encrypted); + size_t written; + + ret = yaca_encrypt_update(ctx, key_material_64, len64, + encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_update(ctx, key_material_256, len256, + encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_update(ctx, key_material_192, len192, + encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + encrypted_len = written; + + ret = yaca_encrypt_update(ctx, key_material_192, len192, + encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_finalize(ctx, encrypted + encrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + encrypted_len += written; + BOOST_REQUIRE(encrypted_len <= total); + ret = yaca_realloc(encrypted_len, (void **)&encrypted); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_encrypt_update(ctx, key_material_192, len192, + encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_finalize(ctx, encrypted + encrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* DECRYPT 3DES */ + { + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_3DES_3TDEA, + YACA_BCM_WRAP, key_sym, YACA_KEY_NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_3DES_3TDEA, + YACA_BCM_WRAP, key_des1, YACA_KEY_NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_3DES_3TDEA, + YACA_BCM_WRAP, key_des2, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_3DES_3TDEA, + YACA_BCM_WRAP, key_des2, YACA_KEY_NULL); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len - 1, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len = written; + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len += written; + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + yaca_key_destroy(key_sym); + yaca_key_destroy(key_des1); + yaca_key_destroy(key_des2); + yaca_key_destroy(iv); + yaca_free(key_material_64); + yaca_free(key_material_192); + yaca_free(key_material_256); + yaca_free(encrypted); +} + +BOOST_FIXTURE_TEST_CASE(T607__positive__encrypt_decrypt_rc2, InitDebugFixture) +{ + struct encrypt_args { + yaca_block_cipher_mode_e bcm; + size_t key_bit_len; + yaca_padding_e padding; + size_t effective_key_bits; + size_t split; + }; + + const std::vector eargs = { + {YACA_BCM_CBC, 128, YACA_INVALID_PADDING, IGNORE, 11}, + {YACA_BCM_CBC, 192, YACA_PADDING_NONE, 64, 22}, + {YACA_BCM_CBC, 200, YACA_PADDING_PKCS7, 128, 3}, + {YACA_BCM_CBC, 192, YACA_INVALID_PADDING, 255, 7}, + {YACA_BCM_CBC, 192, YACA_INVALID_PADDING, 713, 2}, + {YACA_BCM_CBC, 224, YACA_INVALID_PADDING, 1, 19}, + {YACA_BCM_CBC, 256, YACA_INVALID_PADDING, 1024, 19}, + {YACA_BCM_CFB, 192, YACA_INVALID_PADDING, IGNORE, 13}, + {YACA_BCM_CFB, 192, YACA_INVALID_PADDING, 333, 33}, + {YACA_BCM_ECB, 272, YACA_INVALID_PADDING, IGNORE, 8}, + {YACA_BCM_ECB, 192, YACA_PADDING_NONE, 666, 15}, + {YACA_BCM_ECB, 192, YACA_PADDING_PKCS7, 21, 15}, + {YACA_BCM_OFB, 520, YACA_INVALID_PADDING, IGNORE, 25}, + {YACA_BCM_OFB, 224, YACA_INVALID_PADDING, 999, 35}, + }; + + for (const auto &ea: eargs) { + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key = YACA_KEY_NULL, iv = YACA_KEY_NULL; + + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len = 0, decrypted_len = 0; + + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, ea.key_bit_len, &key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + iv = generate_iv(YACA_ENCRYPT_UNSAFE_RC2, ea.bcm, ea.key_bit_len); + + /* ENCRYPT */ + { + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_UNSAFE_RC2, ea.bcm, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + if (ea.padding != YACA_INVALID_PADDING) { + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &ea.padding, sizeof(yaca_padding_e)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + if (ea.effective_key_bits != IGNORE) { + ret = yaca_context_set_property(ctx, YACA_PROPERTY_RC2_EFFECTIVE_KEY_BITS, + &ea.effective_key_bits, sizeof(size_t)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + size_t total = allocate_output(ctx, INPUT_DATA_SIZE, ea.split, encrypted); + size_t written; + + call_update_loop(ctx, INPUT_DATA, INPUT_DATA_SIZE, + encrypted, encrypted_len, ea.split, + &yaca_encrypt_update); + + ret = yaca_encrypt_finalize(ctx, encrypted + encrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + encrypted_len += written; + + BOOST_REQUIRE(encrypted_len <= total); + ret = yaca_realloc(encrypted_len, (void **)&encrypted); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* DECRYPT */ + { + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_UNSAFE_RC2, ea.bcm, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + if (ea.padding != YACA_INVALID_PADDING) { + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &ea.padding, sizeof(yaca_padding_e)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + if (ea.effective_key_bits != IGNORE) { + ret = yaca_context_set_property(ctx, YACA_PROPERTY_RC2_EFFECTIVE_KEY_BITS, + &ea.effective_key_bits, sizeof(size_t)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + size_t total = allocate_output(ctx, encrypted_len, ea.split, decrypted); + size_t written; + + call_update_loop(ctx, encrypted, encrypted_len, + decrypted, decrypted_len, ea.split, + &yaca_decrypt_update); + + ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len += written; + + BOOST_REQUIRE(decrypted_len <= total); + ret = yaca_realloc(decrypted_len, (void **)&decrypted); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + BOOST_REQUIRE(decrypted_len == INPUT_DATA_SIZE); + ret = yaca_memcmp(INPUT_DATA, decrypted, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_key_destroy(key); + yaca_key_destroy(iv); + yaca_free(encrypted); + yaca_free(decrypted); + } +} + +BOOST_FIXTURE_TEST_CASE(T608__negative__encrypt_decrypt_rc2, InitDebugFixture) +{ + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key = YACA_KEY_NULL, iv = YACA_KEY_NULL; + yaca_padding_e pad_invalid = YACA_PADDING_PKCS1_SSLV23; + size_t effective_bits_invalid1 = 0, effective_bits_invalid2 = 2048; + + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_192BIT, &key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_generate(YACA_KEY_TYPE_IV, YACA_KEY_LENGTH_IV_64BIT, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + /* ENCRYPT */ + { + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_UNSAFE_RC2, YACA_BCM_CFB1, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_UNSAFE_RC2, YACA_BCM_CTR, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_UNSAFE_RC2, YACA_BCM_CBC, YACA_KEY_NULL, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_UNSAFE_RC2, YACA_BCM_CBC, key, YACA_KEY_NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_UNSAFE_RC2, YACA_BCM_CBC, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad_invalid, sizeof(yaca_padding_e)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_RC2_EFFECTIVE_KEY_BITS, + &effective_bits_invalid1, sizeof(size_t)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_RC2_EFFECTIVE_KEY_BITS, + &effective_bits_invalid2, sizeof(size_t)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* DECRYPT */ + { + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_UNSAFE_RC2, YACA_BCM_CFB1, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_UNSAFE_RC2, YACA_BCM_CTR, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_UNSAFE_RC2, YACA_BCM_CBC, YACA_KEY_NULL, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_UNSAFE_RC2, YACA_BCM_CBC, key, YACA_KEY_NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_UNSAFE_RC2, YACA_BCM_CBC, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad_invalid, sizeof(yaca_padding_e)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_RC2_EFFECTIVE_KEY_BITS, + &effective_bits_invalid1, sizeof(size_t)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_RC2_EFFECTIVE_KEY_BITS, + &effective_bits_invalid2, sizeof(size_t)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + yaca_key_destroy(key); + yaca_key_destroy(iv); +} + +BOOST_FIXTURE_TEST_CASE(T609__positive__encrypt_decrypt_ccm, InitDebugFixture) +{ + struct encrypt_args { + size_t key_bit_len; + size_t ccm_tag_len; + size_t aad_len; + size_t iv_bit_len; + }; + + const std::vector eargs = { + {128, IGNORE, IGNORE, IGNORE}, + {128, 4, IGNORE, IGNORE}, + {128, IGNORE, 13, IGNORE}, + {128, 6, 23, IGNORE}, + {128, 12, 19, 96}, + {128, 8, 43, 64}, + + {192, IGNORE, IGNORE, IGNORE}, + {192, 10, IGNORE, IGNORE}, + {192, IGNORE, 21, IGNORE}, + {192, 8, 17, IGNORE}, + {192, 16, 29, 64}, + {192, 10, 34, 96}, + + {256, IGNORE, IGNORE, IGNORE}, + {256, 16, IGNORE, IGNORE}, + {256, IGNORE, 55, IGNORE}, + {256, 12, 33, IGNORE}, + {256, 6, 22, 96}, + {256, 10, 44, 64}, + }; + + for (const auto &ea: eargs) { + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key = YACA_KEY_NULL, iv = YACA_KEY_NULL; + + char *tag = NULL, *aad = NULL; + size_t tag_len; + + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len, decrypted_len; + + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, ea.key_bit_len, &key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + iv = generate_iv(YACA_ENCRYPT_AES, YACA_BCM_CCM, ea.key_bit_len, ea.iv_bit_len); + + /* ENCRYPT */ + { + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CCM, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + size_t total = allocate_output(ctx, INPUT_DATA_SIZE, 1, encrypted); + size_t written; + + if (ea.ccm_tag_len != IGNORE) { + tag_len = ea.ccm_tag_len; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG_LEN, + &tag_len, sizeof(tag_len)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + if (ea.aad_len != IGNORE) { + ret = yaca_malloc(ea.aad_len, (void**)&aad); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_randomize_bytes(aad, ea.aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_encrypt_update(ctx, NULL, INPUT_DATA_SIZE, + NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, + aad, ea.aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + ret = yaca_encrypt_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + encrypted_len = written; + + ret = yaca_encrypt_finalize(ctx, encrypted + encrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + encrypted_len += written; + + BOOST_REQUIRE(encrypted_len <= total); + ret = yaca_realloc(encrypted_len, (void **)&encrypted); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_get_property(ctx, YACA_PROPERTY_CCM_TAG, (void**)&tag, &tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* DECRYPT */ + { + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CCM, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + size_t total = allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG, tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + if (ea.aad_len != IGNORE) { + ret = yaca_decrypt_update(ctx, NULL, encrypted_len, + NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, + aad, ea.aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len = written; + + ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len += written; + + BOOST_REQUIRE(decrypted_len <= total); + ret = yaca_realloc(decrypted_len, (void **)&decrypted); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + BOOST_REQUIRE(decrypted_len == INPUT_DATA_SIZE); + ret = yaca_memcmp(INPUT_DATA, decrypted, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_key_destroy(key); + yaca_key_destroy(iv); + yaca_free(encrypted); + yaca_free(decrypted); + yaca_free(tag); + yaca_free(aad); + } +} + +BOOST_FIXTURE_TEST_CASE(T610__negative__encrypt_decrypt_ccm, InitDebugFixture) +{ + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key = YACA_KEY_NULL, key2 = YACA_KEY_NULL; + yaca_key_h iv = YACA_KEY_NULL, iv2 = YACA_KEY_NULL; + yaca_key_h iv_invalid = YACA_KEY_NULL; + + char *tag = NULL, *aad = NULL; + size_t tag_len = 0, tag_len_invalid = 17, aad_len = 55; + + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len, decrypted_len; + + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_256BIT, &key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_256BIT, &key2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_generate(YACA_KEY_TYPE_IV, 96, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_generate(YACA_KEY_TYPE_IV, 96, &iv2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_generate(YACA_KEY_TYPE_IV, 128, &iv_invalid); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_malloc(aad_len, (void**)&aad); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_randomize_bytes(aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + /* ENCRYPT, AAD without pre-update */ + { + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CCM, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* ENCRYPT, pre-update without AAD */ + { + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CCM, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, INPUT_DATA_SIZE, 1, encrypted); + size_t written; + + ret = yaca_encrypt_update(ctx, NULL, INPUT_DATA_SIZE, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_encrypt_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(encrypted); + encrypted = NULL; + } + + /* ENCRYPT */ + { + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CCM, key, YACA_KEY_NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CCM, key, iv_invalid); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CCM, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + size_t total = allocate_output(ctx, INPUT_DATA_SIZE, 1, encrypted); + size_t written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG_LEN, + &tag_len_invalid, sizeof(tag_len_invalid)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_update(ctx, NULL, INPUT_DATA_SIZE, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_get_property(ctx, YACA_PROPERTY_CCM_TAG, (void**)&tag, &tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_update(ctx, NULL, INPUT_DATA_SIZE, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_encrypt_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_encrypt_update(ctx, NULL, INPUT_DATA_SIZE, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + encrypted_len = written; + + ret = yaca_encrypt_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_finalize(ctx, encrypted + encrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + encrypted_len += written; + BOOST_REQUIRE(encrypted_len <= total); + ret = yaca_realloc(encrypted_len, (void **)&encrypted); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_finalize(ctx, encrypted + encrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_get_property(ctx, YACA_PROPERTY_CCM_TAG, (void**)&tag, &tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* DECRYPT, no TAG */ + { + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CCM, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_decrypt_update(ctx, NULL, encrypted_len, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_free(decrypted); + decrypted = NULL; + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* DECRYPT, AAD without pre-update */ + { + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CCM, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG, tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* DECRYPT, pre-update without AAD */ + { + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CCM, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG, tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_decrypt_update(ctx, NULL, INPUT_DATA_SIZE, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + /* DECRYPT, no AAD */ + { + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CCM, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG, tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + /* DECRYPT */ + { + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CCM, key, YACA_KEY_NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CCM, key, iv_invalid); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CCM, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG, tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_decrypt_update(ctx, NULL, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_update(ctx, NULL, encrypted_len, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_decrypt_update(ctx, NULL, encrypted_len, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len = written; + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG, tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + /* DECRYPT, wrong key */ + { + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CCM, key2, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG, tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_decrypt_update(ctx, NULL, encrypted_len, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + /* In case of AES/CBC wrong key returned INVALID_PASS + * Why this inconsistency? + */ + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + /* DECRYPT, wrong IV */ + { + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CCM, key, iv2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG, tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_decrypt_update(ctx, NULL, encrypted_len, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + /* DECRYPT, broken TAG */ + { + char *tag2 = NULL; + ret = yaca_malloc(tag_len, (void**)&tag2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + memcpy((void*)tag2, (void*)tag, tag_len); + tag2[0] = ~tag2[0]; + tag2[1] = ~tag2[1]; + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CCM, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG, tag2, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_decrypt_update(ctx, NULL, encrypted_len, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + yaca_free(tag2); + } + + /* DECRYPT, broken AAD */ + { + char *aad2 = NULL; + ret = yaca_malloc(aad_len, (void**)&aad2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + memcpy((void*)aad2, (void*)aad, aad_len); + aad2[0] = ~aad2[0]; + aad2[1] = ~aad2[1]; + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CCM, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG, tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_decrypt_update(ctx, NULL, encrypted_len, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, aad2, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + yaca_free(aad2); + } + + /* DECRYPT, broken ciphertext */ + { + encrypted[0] = ~encrypted[0]; + encrypted[1] = ~encrypted[1]; + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CCM, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG, tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_decrypt_update(ctx, NULL, encrypted_len, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + yaca_key_destroy(key); + yaca_key_destroy(key2); + yaca_key_destroy(iv); + yaca_key_destroy(iv2); + yaca_free(encrypted); + yaca_free(tag); + yaca_free(aad); +} + +BOOST_FIXTURE_TEST_CASE(T611__positive__encrypt_decrypt_gcm, InitDebugFixture) +{ + struct encrypt_args { + size_t key_bit_len; + size_t gcm_tag_len; + size_t aad_len; + size_t split; + size_t iv_bit_len; + }; + + const std::vector eargs = { + {128, IGNORE, IGNORE, 11, IGNORE}, + {128, 4, IGNORE, 12, IGNORE}, + {128, IGNORE, 21, 13, IGNORE}, + {128, 13, 22, 14, IGNORE}, + {128, 14, 80, 4, 128}, + {128, 13, 22, 14, 96}, + + {192, IGNORE, IGNORE, 22, IGNORE}, + {192, 8, IGNORE, 23, IGNORE}, + {192, IGNORE, 32, 24, IGNORE}, + {192, 15, 33, 25, IGNORE}, + {192, 13, 30, 74, 64}, + {192, 15, 37, 25, 96}, + + {256, IGNORE, IGNORE, 33, IGNORE}, + {256, 14, IGNORE, 34, IGNORE}, + {256, IGNORE, 17, 35, IGNORE}, + {256, 16, 44, 36, IGNORE}, + {256, 14, 12, 15, 128}, + {256, 16, 45, 36, 96}, + }; + + for (const auto &ea: eargs) { + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key = YACA_KEY_NULL, iv = YACA_KEY_NULL; + + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len = 0, decrypted_len = 0; + + char *tag = NULL, *aad = NULL; + size_t tag_len; + + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, ea.key_bit_len, &key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + iv = generate_iv(YACA_ENCRYPT_AES, YACA_BCM_GCM, ea.key_bit_len, ea.iv_bit_len); + + /* ENCRYPT */ + { + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_GCM, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + size_t total = allocate_output(ctx, INPUT_DATA_SIZE, ea.split, encrypted); + size_t written; + + if (ea.aad_len != IGNORE) { + ret = yaca_malloc(ea.aad_len, (void**)&aad); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_randomize_bytes(aad, ea.aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_AAD, + aad, ea.aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + call_update_loop(ctx, INPUT_DATA, INPUT_DATA_SIZE, + encrypted, encrypted_len, ea.split, + yaca_encrypt_update); + + ret = yaca_encrypt_finalize(ctx, encrypted + encrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + encrypted_len += written; + + BOOST_REQUIRE(encrypted_len <= total); + ret = yaca_realloc(encrypted_len, (void **)&encrypted); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + if (ea.gcm_tag_len != IGNORE) { + tag_len = ea.gcm_tag_len; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_TAG_LEN, + &tag_len, sizeof(tag_len)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + ret = yaca_context_get_property(ctx, YACA_PROPERTY_GCM_TAG, + (void**)&tag, &tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* DECRYPT */ + { + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_GCM, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + size_t total = allocate_output(ctx, encrypted_len, ea.split, decrypted); + size_t written; + + if (ea.aad_len != IGNORE) { + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_AAD, + aad, ea.aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + call_update_loop(ctx, encrypted, encrypted_len, + decrypted, decrypted_len, ea.split, + yaca_decrypt_update); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_TAG, + tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len += written; + + BOOST_REQUIRE(decrypted_len <= total); + ret = yaca_realloc(decrypted_len, (void **)&decrypted); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + BOOST_REQUIRE(decrypted_len == INPUT_DATA_SIZE); + ret = yaca_memcmp(INPUT_DATA, decrypted, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_key_destroy(key); + yaca_key_destroy(iv); + yaca_free(encrypted); + yaca_free(decrypted); + yaca_free(tag); + yaca_free(aad); + } +} + +BOOST_FIXTURE_TEST_CASE(T612__negative__encrypt_decrypt_gcm, InitDebugFixture) +{ + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key = YACA_KEY_NULL, key2 = YACA_KEY_NULL; + yaca_key_h iv = YACA_KEY_NULL, iv2 = YACA_KEY_NULL; + + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len = 0, decrypted_len = 0; + + char *tag = NULL, *aad = NULL; + size_t tag_len = 0, tag_len_invalid = 17, aad_len = 55; + + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_256BIT, &key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_256BIT, &key2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_generate(YACA_KEY_TYPE_IV, 96, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_generate(YACA_KEY_TYPE_IV, 96, &iv2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_malloc(aad_len, (void**)&aad); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_randomize_bytes(aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + /* ENCRYPT */ + { + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_GCM, key, YACA_KEY_NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_GCM, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + size_t total = allocate_output(ctx, INPUT_DATA_SIZE, 1, encrypted); + size_t written; + + ret = yaca_encrypt_update(ctx, NULL, INPUT_DATA_SIZE, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_encrypt_update(ctx, NULL, INPUT_DATA_SIZE, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_get_property(ctx, YACA_PROPERTY_GCM_TAG, + (void**)&tag, &tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + encrypted_len = written; + + ret = yaca_encrypt_finalize(ctx, encrypted + encrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + encrypted_len += written; + BOOST_REQUIRE(encrypted_len <= total); + ret = yaca_realloc(encrypted_len, (void **)&encrypted); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_encrypt_finalize(ctx, encrypted + encrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_TAG_LEN, + &tag_len_invalid, sizeof(tag_len_invalid)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_get_property(ctx, YACA_PROPERTY_GCM_TAG, + (void**)&tag, &tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* DECRYPT, no TAG */ + { + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_GCM, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len = written; + + ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + /* DECRYPT, no AAD */ + { + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_GCM, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_TAG, tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + /* DECRYPT */ + { + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_GCM, key, YACA_KEY_NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_GCM, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_decrypt_update(ctx, NULL, INPUT_DATA_SIZE, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_decrypt_update(ctx, NULL, INPUT_DATA_SIZE, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len = written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_TAG, tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_TAG, tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + /* DECRYPT, wrong key */ + { + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_GCM, key2, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len = written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_TAG, tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + /* DECRYPT, wrong IV */ + { + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_GCM, key, iv2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len = written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_TAG, tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + /* DECRYPT, broken TAG */ + { + char *tag2 = NULL; + ret = yaca_malloc(tag_len, (void**)&tag2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + memcpy((void*)tag2, (void*)tag, tag_len); + tag2[0] = ~tag2[0]; + tag2[1] = ~tag2[1]; + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_GCM, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len = written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_TAG, tag2, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + /* DECRYPT, broken AAD */ + { + char *aad2 = NULL; + ret = yaca_malloc(aad_len, (void**)&aad2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + memcpy((void*)aad2, (void*)aad, aad_len); + aad2[0] = ~aad2[0]; + aad2[1] = ~aad2[1]; + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_GCM, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_AAD, aad2, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len = written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_TAG, tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + /* DECRYPT, broken ciphertext */ + { + encrypted[0] = ~encrypted[0]; + encrypted[1] = ~encrypted[1]; + + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_GCM, key, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len = written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_TAG, tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + yaca_key_destroy(key); + yaca_key_destroy(key2); + yaca_key_destroy(iv); + yaca_key_destroy(iv2); + yaca_free(encrypted); + yaca_free(tag); + yaca_free(aad); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/test_key.cpp b/tests/test_key.cpp new file mode 100644 index 0000000..d2ba692 --- /dev/null +++ b/tests/test_key.cpp @@ -0,0 +1,1448 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Pawelczyk + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file test_key.cpp + * @author Lukasz Pawelczyk + * @brief Key API unit tests. + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "common.h" + + +namespace { + +void import_export(yaca_key_h key, yaca_key_type_e expected_type, + yaca_key_bit_length_e expected_len, const char *password, + yaca_key_format_e format, yaca_key_file_format_e file_format) +{ + int ret; + yaca_key_h imported = YACA_KEY_NULL; + + char *data1 = NULL, *data2 = NULL; + size_t data1_len = 0, data2_len = 0; + yaca_key_type_e key_type; + size_t key_length; + + ret = yaca_key_export(key, format, file_format, + password, &data1, &data1_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + BOOST_REQUIRE(data1 != NULL); + BOOST_REQUIRE(data1_len > 0); + + ret = yaca_key_import(expected_type, password, data1, data1_len, &imported); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_key_get_type(imported, &key_type); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_get_bit_length(imported, &key_length); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + BOOST_REQUIRE(key_type == expected_type); + BOOST_REQUIRE(key_length == expected_len); + + ret = yaca_key_export(imported, format, file_format, + password, &data2, &data2_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + BOOST_REQUIRE(data2 != NULL); + BOOST_REQUIRE(data2_len > 0); + + BOOST_REQUIRE(data1_len == data2_len); + + if (password == NULL || password[0] == '\0') { + ret = yaca_memcmp(data1, data2, data1_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + yaca_key_destroy(imported); + yaca_free(data1); + yaca_free(data2); +} + +void assert_keys_identical(const yaca_key_h key1, const yaca_key_h key2) +{ + int ret; + char *data1 = NULL, *data2 = NULL; + size_t len1, len2, data1_len, data2_len; + yaca_key_type_e type1, type2; + yaca_key_file_format_e format; + + ret = yaca_key_get_bit_length(key1, &len1); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_get_bit_length(key2, &len2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + BOOST_REQUIRE(len1 == len2); + + ret = yaca_key_get_type(key1, &type1); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_get_type(key2, &type2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + BOOST_REQUIRE(type1 == type2); + + switch (type1) { + case YACA_KEY_TYPE_SYMMETRIC: + case YACA_KEY_TYPE_DES: + case YACA_KEY_TYPE_IV: + format = YACA_KEY_FILE_FORMAT_RAW; + break; + default: + format = YACA_KEY_FILE_FORMAT_DER; + } + + ret = yaca_key_export(key1, YACA_KEY_FORMAT_DEFAULT, format, + NULL, &data1, &data1_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_export(key2, YACA_KEY_FORMAT_DEFAULT, format, + NULL, &data2, &data2_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + BOOST_REQUIRE(data1_len == data2_len); + + ret = yaca_memcmp(data1, data2, data1_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_free(data1); + yaca_free(data2); +} + +} // namespace + + +BOOST_AUTO_TEST_SUITE(TESTS_KEY) + +BOOST_FIXTURE_TEST_CASE(T201__positive__key_generate, InitDebugFixture) +{ + struct key_args { + yaca_key_type_e type; + size_t len; + size_t expected; + }; + + const std::vector kargs = { + {YACA_KEY_TYPE_SYMMETRIC, + YACA_KEY_LENGTH_256BIT, + YACA_KEY_LENGTH_256BIT}, + {YACA_KEY_TYPE_SYMMETRIC, + 200, + 200}, + {YACA_KEY_TYPE_SYMMETRIC, + 104, + 104}, + {YACA_KEY_TYPE_DES, + YACA_KEY_LENGTH_192BIT, + YACA_KEY_LENGTH_192BIT}, + {YACA_KEY_TYPE_IV, + YACA_KEY_LENGTH_512BIT, + YACA_KEY_LENGTH_512BIT}, + {YACA_KEY_TYPE_RSA_PRIV, + YACA_KEY_LENGTH_2048BIT, + YACA_KEY_LENGTH_2048BIT}, + {YACA_KEY_TYPE_RSA_PRIV, + 520, + 520}, + {YACA_KEY_TYPE_RSA_PRIV, + 1056, + 1056}, + {YACA_KEY_TYPE_DSA_PRIV, + YACA_KEY_LENGTH_2048BIT, + YACA_KEY_LENGTH_2048BIT}, + {YACA_KEY_TYPE_DSA_PRIV, + 576, + 576}, + {YACA_KEY_TYPE_DSA_PRIV, + 896, + 896}, + {YACA_KEY_TYPE_DH_PRIV, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_DH_RFC_2048_224, + YACA_KEY_LENGTH_2048BIT}, + {YACA_KEY_TYPE_DH_PRIV, + (yaca_key_bit_length_e)(YACA_KEY_LENGTH_DH_GENERATOR_2 | 264), + 264}, + {YACA_KEY_TYPE_DH_PRIV, + (yaca_key_bit_length_e)(YACA_KEY_LENGTH_DH_GENERATOR_5 | 376), + 376}, + {YACA_KEY_TYPE_EC_PRIV, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_EC_SECP384R1, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_EC_SECP384R1} + }; + + for (const auto &ka: kargs) { + int ret; + yaca_key_h key = YACA_KEY_NULL; + yaca_key_type_e key_type; + size_t key_length; + + ret = yaca_key_generate(ka.type, ka.len, &key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_key_get_type(key, &key_type); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_get_bit_length(key, &key_length); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + BOOST_REQUIRE(key_type == ka.type); + BOOST_REQUIRE(key_length == ka.expected); + + yaca_key_destroy(key); + } +} + +BOOST_FIXTURE_TEST_CASE(T202__negative__key_generate, InitDebugFixture) +{ + int ret; + yaca_key_h key = YACA_KEY_NULL; + + ret = yaca_key_generate(YACA_INVALID_KEY_TYPE, YACA_KEY_LENGTH_256BIT, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_256BIT, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_generate(YACA_KEY_TYPE_RSA_PUB, YACA_KEY_LENGTH_1024BIT, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_generate(YACA_KEY_TYPE_DSA_PARAMS, YACA_KEY_LENGTH_256BIT, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, 0, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, 255, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_generate(YACA_KEY_TYPE_DES, 127, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_generate(YACA_KEY_TYPE_RSA_PRIV, 2047, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_generate(YACA_KEY_TYPE_DH_PRIV, + YACA_KEY_LENGTH_DH_GENERATOR_2 | 192U, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_generate(YACA_KEY_TYPE_DH_PRIV, YACA_KEYLEN_COMPONENT_TYPE_DH | + YACA_KEYLEN_COMPONENT_DH_GEN_MASK | 1024U, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_generate(YACA_KEY_TYPE_DH_PRIV, YACA_KEYLEN_COMPONENT_TYPE_MASK | + YACA_KEYLEN_COMPONENT_DH_GEN_2 | 1024U, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_generate(YACA_KEY_TYPE_DH_PRIV, YACA_KEYLEN_COMPONENT_TYPE_DH_RFC, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_generate(YACA_KEY_TYPE_EC_PARAMS, YACA_KEYLEN_COMPONENT_EC_SECT, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); +} + +BOOST_FIXTURE_TEST_CASE(T203__positive__key_generate_from_parameters, InitDebugFixture) +{ + struct key_args { + yaca_key_type_e type_params; + yaca_key_type_e type_key; + yaca_key_bit_length_e len; + yaca_key_bit_length_e expected; + }; + + const std::vector kargs = { + {YACA_KEY_TYPE_DSA_PARAMS, + YACA_KEY_TYPE_DSA_PRIV, + YACA_KEY_LENGTH_1024BIT, + YACA_KEY_LENGTH_1024BIT}, + {YACA_KEY_TYPE_DH_PARAMS, + YACA_KEY_TYPE_DH_PRIV, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_DH_RFC_1024_160, + YACA_KEY_LENGTH_1024BIT}, + {YACA_KEY_TYPE_DH_PARAMS, + YACA_KEY_TYPE_DH_PRIV, + (yaca_key_bit_length_e)(YACA_KEY_LENGTH_DH_GENERATOR_2 | 1024U), + YACA_KEY_LENGTH_1024BIT}, + {YACA_KEY_TYPE_DH_PARAMS, + YACA_KEY_TYPE_DH_PRIV, + (yaca_key_bit_length_e)(YACA_KEY_LENGTH_DH_GENERATOR_5 | 512U), + YACA_KEY_LENGTH_512BIT}, + {YACA_KEY_TYPE_EC_PARAMS, + YACA_KEY_TYPE_EC_PRIV, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_EC_PRIME256V1, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_EC_PRIME256V1} + }; + + for (const auto &ka: kargs) { + int ret; + yaca_key_h params = YACA_KEY_NULL; + yaca_key_h key = YACA_KEY_NULL; + yaca_key_type_e key_type; + size_t key_length; + + ret = yaca_key_generate(ka.type_params, ka.len, ¶ms); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_key_get_type(params, &key_type); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_get_bit_length(params, &key_length); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + BOOST_REQUIRE(key_type == ka.type_params); + BOOST_REQUIRE(key_length == ka.expected); + + ret = yaca_key_generate_from_parameters(params, &key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_key_get_type(key, &key_type); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_get_bit_length(key, &key_length); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + BOOST_REQUIRE(key_type == ka.type_key); + BOOST_REQUIRE(key_length == ka.expected); + + + yaca_key_destroy(params); + yaca_key_destroy(key); + } +} + +BOOST_FIXTURE_TEST_CASE(T204__negative__key_generate_from_parameters, InitDebugFixture) +{ + int ret; + yaca_key_h key_prv = YACA_KEY_NULL, key_pub = YACA_KEY_NULL; + yaca_key_h key_sym = YACA_KEY_NULL, key_params = YACA_KEY_NULL; + yaca_key_h key = YACA_KEY_NULL; + + generate_asymmetric_keys(YACA_KEY_TYPE_DSA_PRIV, YACA_KEY_LENGTH_512BIT, + &key_prv, &key_pub, &key_params); + + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_UNSAFE_128BIT, &key_sym); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_key_generate_from_parameters(YACA_KEY_NULL, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_generate_from_parameters(key_prv, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_generate_from_parameters(key_pub, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_generate_from_parameters(key_sym, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_generate_from_parameters(key_params, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_key_destroy(key_prv); + yaca_key_destroy(key_pub); + yaca_key_destroy(key_params); + yaca_key_destroy(key_sym); +} + +BOOST_FIXTURE_TEST_CASE(T205__positive__key_extract_public_parameters, InitDebugFixture) +{ + struct key_args { + yaca_key_type_e type_priv; + yaca_key_type_e type_pub; + yaca_key_type_e type_params; + yaca_key_bit_length_e len; + yaca_key_bit_length_e expected; + }; + + const std::vector kargs = { + {YACA_KEY_TYPE_RSA_PRIV, + YACA_KEY_TYPE_RSA_PUB, + YACA_INVALID_KEY_TYPE, + YACA_KEY_LENGTH_1024BIT, + YACA_KEY_LENGTH_1024BIT}, + {YACA_KEY_TYPE_DSA_PRIV, + YACA_KEY_TYPE_DSA_PUB, + YACA_KEY_TYPE_DSA_PARAMS, + YACA_KEY_LENGTH_1024BIT, + YACA_KEY_LENGTH_1024BIT}, + {YACA_KEY_TYPE_DH_PRIV, + YACA_KEY_TYPE_DH_PUB, + YACA_KEY_TYPE_DH_PARAMS, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_DH_RFC_2048_256, + YACA_KEY_LENGTH_2048BIT}, + {YACA_KEY_TYPE_EC_PRIV, + YACA_KEY_TYPE_EC_PUB, + YACA_KEY_TYPE_EC_PARAMS, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_EC_PRIME256V1, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_EC_PRIME256V1} + }; + + for (const auto &ka: kargs) { + int ret; + yaca_key_h priv = YACA_KEY_NULL; + yaca_key_h pub = YACA_KEY_NULL; + yaca_key_type_e key_type; + size_t key_length; + + ret = yaca_key_generate(ka.type_priv, ka.len, &priv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_key_extract_public(priv, &pub); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_key_get_type(pub, &key_type); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_get_bit_length(pub, &key_length); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + BOOST_REQUIRE(key_type == ka.type_pub); + BOOST_REQUIRE(key_length == ka.expected); + + if (ka.type_params != YACA_INVALID_KEY_TYPE) { + yaca_key_h params = YACA_KEY_NULL; + yaca_key_h key = YACA_KEY_NULL; + + ret = yaca_key_extract_parameters(pub, ¶ms); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_key_get_type(params, &key_type); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_get_bit_length(params, &key_length); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + BOOST_REQUIRE(key_type == ka.type_params); + BOOST_REQUIRE(key_length == ka.expected); + + ret = yaca_key_generate_from_parameters(params, &key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_key_get_type(key, &key_type); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_get_bit_length(key, &key_length); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + BOOST_REQUIRE(key_type == ka.type_priv); + BOOST_REQUIRE(key_length == ka.expected); + + yaca_key_destroy(params); + yaca_key_destroy(key); + } + + yaca_key_destroy(priv); + yaca_key_destroy(pub); + } +} + +BOOST_FIXTURE_TEST_CASE(T206__negative__key_extract_public_parameters, InitDebugFixture) +{ + int ret; + yaca_key_h key_prv = YACA_KEY_NULL, key_pub = YACA_KEY_NULL; + yaca_key_h key_sym = YACA_KEY_NULL, key_params = YACA_KEY_NULL; + yaca_key_h key = YACA_KEY_NULL; + + generate_asymmetric_keys(YACA_KEY_TYPE_DSA_PRIV, YACA_KEY_LENGTH_512BIT, &key_prv, &key_pub, &key_params); + + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_UNSAFE_128BIT, &key_sym); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_key_extract_public(NULL, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_extract_public(key_pub, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_extract_public(key_params, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_extract_public(key_sym, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_extract_public(key_prv, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_extract_parameters(NULL, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_extract_parameters(key_params, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_extract_parameters(key_sym, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_extract_parameters(key_prv, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_key_destroy(key_prv); + yaca_key_destroy(key_pub); + yaca_key_destroy(key_params); + yaca_key_destroy(key_sym); +} + +BOOST_FIXTURE_TEST_CASE(T207__positive__key_import_export_symmetric, InitDebugFixture) +{ + struct key_args { + yaca_key_type_e type; + yaca_key_bit_length_e len; + }; + + struct format_args { + yaca_key_format_e format; + yaca_key_file_format_e file_format; + }; + + const std::vector kargs = { + {YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_256BIT}, + {YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_512BIT}, + {YACA_KEY_TYPE_IV, YACA_KEY_LENGTH_UNSAFE_128BIT}, + {YACA_KEY_TYPE_DES, YACA_KEY_LENGTH_UNSAFE_128BIT}, + {YACA_KEY_TYPE_DES, YACA_KEY_LENGTH_192BIT} + }; + + for (const auto &ka: kargs) { + int ret; + yaca_key_h key = YACA_KEY_NULL; + + ret = yaca_key_generate(ka.type, ka.len, &key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + import_export(key, ka.type, ka.len, "", + YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_RAW); + + import_export(key, ka.type, ka.len, "", + YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_BASE64); + + yaca_key_destroy(key); + } +} + +BOOST_FIXTURE_TEST_CASE(T208__negative__key_import_export_symmetric, InitDebugFixture) +{ + int ret; + yaca_key_h key = YACA_KEY_NULL, key_import = YACA_KEY_NULL; + yaca_key_type_e type; + size_t len; + + char *data = NULL; + size_t data_len; + + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_256BIT, &key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_key_export(YACA_KEY_NULL, YACA_KEY_FORMAT_DEFAULT, + YACA_KEY_FILE_FORMAT_BASE64, NULL, &data, &data_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_export(key, YACA_INVALID_KEY_FORMAT, + YACA_KEY_FILE_FORMAT_BASE64, NULL, &data, &data_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_export(key, YACA_KEY_FORMAT_PKCS8, + YACA_KEY_FILE_FORMAT_BASE64, NULL, &data, &data_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_export(key, YACA_KEY_FORMAT_DEFAULT, + YACA_INVALID_KEY_FILE_FORMAT, NULL, &data, &data_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_export(key, YACA_KEY_FORMAT_DEFAULT, + YACA_KEY_FILE_FORMAT_PEM, NULL, &data, &data_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_export(key, YACA_KEY_FORMAT_DEFAULT, + YACA_KEY_FILE_FORMAT_BASE64, "password", &data, &data_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_export(key, YACA_KEY_FORMAT_DEFAULT, + YACA_KEY_FILE_FORMAT_BASE64, NULL, NULL, &data_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_export(key, YACA_KEY_FORMAT_DEFAULT, + YACA_KEY_FILE_FORMAT_BASE64, NULL, &data, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_export(key, YACA_KEY_FORMAT_DEFAULT, + YACA_KEY_FILE_FORMAT_BASE64, NULL, &data, &data_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_key_import(YACA_INVALID_KEY_TYPE, "", data, data_len, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_import(YACA_KEY_TYPE_DH_PRIV, "", data, data_len, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_import(YACA_KEY_TYPE_DES, "", data, data_len, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_import(YACA_KEY_TYPE_SYMMETRIC, "password", data, data_len, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_import(YACA_KEY_TYPE_SYMMETRIC, "", NULL, data_len, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_import(YACA_KEY_TYPE_SYMMETRIC, "", data, 0, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_import(YACA_KEY_TYPE_SYMMETRIC, "", data, data_len, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + /* should still be correct */ + data[0] = (data[0] == 'A' ? 'Z' : 'A'); + ret = yaca_key_import(YACA_KEY_TYPE_SYMMETRIC, "", data, data_len, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_key_get_type(key_import, &type); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + BOOST_REQUIRE(type == YACA_KEY_TYPE_SYMMETRIC); + ret = yaca_key_get_bit_length(key_import, &len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + BOOST_REQUIRE(len == YACA_KEY_LENGTH_256BIT); + + yaca_key_destroy(key_import); + + /* should be treated as raw */ + ret = yaca_key_import(YACA_KEY_TYPE_SYMMETRIC, "", data, data_len-1, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_key_get_type(key_import, &type); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + BOOST_REQUIRE(type == YACA_KEY_TYPE_SYMMETRIC); + ret = yaca_key_get_bit_length(key_import, &len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + BOOST_REQUIRE(len == 344); + + yaca_key_destroy(key_import); + + /* should be treated as raw */ + data[0] = 10; + ret = yaca_key_import(YACA_KEY_TYPE_SYMMETRIC, "", data, data_len, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_key_get_type(key_import, &type); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + BOOST_REQUIRE(type == YACA_KEY_TYPE_SYMMETRIC); + ret = yaca_key_get_bit_length(key_import, &len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + BOOST_REQUIRE(len == 352); + + yaca_key_destroy(key_import); + yaca_key_destroy(key); + yaca_free(data); +} + +BOOST_FIXTURE_TEST_CASE(T209__positive__key_import_export_asymmetric, InitDebugFixture) +{ + struct key_args { + yaca_key_type_e type_priv; + yaca_key_type_e type_pub; + yaca_key_type_e type_params; + yaca_key_bit_length_e len; + yaca_key_bit_length_e expected; + }; + + struct format_args { + yaca_key_format_e format; + yaca_key_file_format_e file_format; + }; + + const std::vector kargs = { + {YACA_KEY_TYPE_RSA_PRIV, + YACA_KEY_TYPE_RSA_PUB, + YACA_INVALID_KEY_TYPE, + YACA_KEY_LENGTH_1024BIT, + YACA_KEY_LENGTH_1024BIT}, + {YACA_KEY_TYPE_DSA_PRIV, + YACA_KEY_TYPE_DSA_PUB, + YACA_KEY_TYPE_DSA_PARAMS, + YACA_KEY_LENGTH_1024BIT, + YACA_KEY_LENGTH_1024BIT}, + {YACA_KEY_TYPE_EC_PRIV, + YACA_KEY_TYPE_EC_PUB, + YACA_KEY_TYPE_EC_PARAMS, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_EC_PRIME256V1, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_EC_PRIME256V1}, + {YACA_KEY_TYPE_DH_PRIV, + YACA_KEY_TYPE_DH_PUB, + YACA_KEY_TYPE_DH_PARAMS, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_DH_RFC_1024_160, + YACA_KEY_LENGTH_1024BIT} + }; + + for (const auto &ka: kargs) { + int ret; + yaca_key_h key_priv = YACA_KEY_NULL; + yaca_key_h key_pub = YACA_KEY_NULL; + + ret = yaca_key_generate(ka.type_priv, ka.len, &key_priv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + import_export(key_priv, ka.type_priv, ka.expected, NULL, + YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_DER); + + import_export(key_priv, ka.type_priv, ka.expected, NULL, + YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_PEM); + + ret = yaca_key_extract_public(key_priv, &key_pub); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + import_export(key_pub, ka.type_pub, ka.expected, "", + YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_DER); + + import_export(key_pub, ka.type_pub, ka.expected, "", + YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_PEM); + + if (ka.type_params != YACA_INVALID_KEY_TYPE) { + yaca_key_h key_params = YACA_KEY_NULL; + + ret = yaca_key_extract_parameters(key_priv, &key_params); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + import_export(key_params, ka.type_params, ka.expected, NULL, + YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_DER); + + import_export(key_params, ka.type_params, ka.expected, NULL, + YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_PEM); + + yaca_key_destroy(key_params); + } + + yaca_key_destroy(key_priv); + yaca_key_destroy(key_pub); + } +} + +BOOST_FIXTURE_TEST_CASE(T210__negative__key_import_export_asymmetric, InitDebugFixture) +{ + int ret; + yaca_key_h key_prv = YACA_KEY_NULL, key_pub; + yaca_key_h key_params = YACA_KEY_NULL, key_import = YACA_KEY_NULL; + char data_short[] = "abc"; + + char *data_pem = NULL, *data_der = NULL; + size_t data_pem_len, data_der_len; + + generate_asymmetric_keys(YACA_KEY_TYPE_DSA_PRIV, YACA_KEY_LENGTH_1024BIT, &key_prv, &key_pub, &key_params); + + ret = yaca_key_export(YACA_KEY_NULL, YACA_KEY_FORMAT_DEFAULT, + YACA_KEY_FILE_FORMAT_PEM, "", &data_pem, &data_pem_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_export(key_prv, YACA_INVALID_KEY_FORMAT, + YACA_KEY_FILE_FORMAT_PEM, "", &data_pem, &data_pem_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_export(key_prv, YACA_KEY_FORMAT_PKCS8, + YACA_KEY_FILE_FORMAT_PEM, "", &data_pem, &data_pem_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_export(key_prv, YACA_KEY_FORMAT_DEFAULT, + YACA_INVALID_KEY_FILE_FORMAT, "", &data_pem, &data_pem_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_export(key_prv, YACA_KEY_FORMAT_DEFAULT, + YACA_KEY_FILE_FORMAT_BASE64, "", &data_pem, &data_pem_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_export(key_prv, YACA_KEY_FORMAT_DEFAULT, + YACA_KEY_FILE_FORMAT_DER, "password", &data_der, &data_der_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_export(key_prv, YACA_KEY_FORMAT_DEFAULT, + YACA_KEY_FILE_FORMAT_PEM, "", NULL, &data_pem_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_export(key_prv, YACA_KEY_FORMAT_DEFAULT, + YACA_KEY_FILE_FORMAT_PEM, "", &data_pem, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_export(key_prv, YACA_KEY_FORMAT_DEFAULT, + YACA_KEY_FILE_FORMAT_PEM, "", &data_pem, &data_pem_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_export(key_prv, YACA_KEY_FORMAT_DEFAULT, + YACA_KEY_FILE_FORMAT_DER, "", &data_der, &data_der_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_key_import(YACA_INVALID_KEY_TYPE, "", data_pem, data_pem_len, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_import(YACA_KEY_TYPE_RSA_PRIV, "", data_pem, data_pem_len, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PUB, "", data_pem, data_pem_len, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PARAMS, "", data_der, data_der_len, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PRIV, "password", data_pem, data_pem_len, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PASSWORD); + + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PRIV, "password", data_der, data_der_len, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PRIV, "", NULL, data_pem_len, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PRIV, "", data_pem, 0, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PRIV, "", data_pem, data_pem_len, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_import(YACA_KEY_TYPE_RSA_PRIV, "", data_short, strlen(data_short), &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + /* two bytes have to be removed to get EINVAL, one is not enough, it's probably newline */ + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PRIV, "", data_pem, data_pem_len - 2, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PRIV, "", data_der, data_der_len - 1, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PRIV, "", data_pem + 1, data_pem_len - 1, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PRIV, "", data_der + 1, data_der_len - 1, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + data_pem[30] = (data_pem[30] == 'a' ? 'z' : 'a'); + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PRIV, "", data_pem, data_pem_len, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + data_der[0] = ~data_der[0]; + data_der[1] = ~data_der[1]; + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PRIV, "", data_der, data_der_len, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_key_destroy(key_prv); + yaca_key_destroy(key_pub); + yaca_key_destroy(key_params); + yaca_free(data_der); + yaca_free(data_pem); +} + +BOOST_FIXTURE_TEST_CASE(T211__positive__key_import_export_encrypted, InitDebugFixture) +{ + static const char *PASSWORD = "ExamplE_PassworD"; + + struct default_args { + yaca_key_type_e type; + yaca_key_bit_length_e len; + }; + + const std::vector dargs = { + {YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_1024BIT}, + {YACA_KEY_TYPE_DSA_PRIV, YACA_KEY_LENGTH_1024BIT} + }; + + for (const auto &da: dargs) { + int ret; + yaca_key_h key = YACA_KEY_NULL; + + ret = yaca_key_generate(da.type, da.len, &key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + import_export(key, da.type, da.len, PASSWORD, + YACA_KEY_FORMAT_DEFAULT, + YACA_KEY_FILE_FORMAT_PEM); + + yaca_key_destroy(key); + } + + struct pkcs8_args { + yaca_key_type_e type; + yaca_key_bit_length_e len; + yaca_key_bit_length_e expected; + }; + + const std::vector pargs { + {YACA_KEY_TYPE_RSA_PRIV, + YACA_KEY_LENGTH_1024BIT, + YACA_KEY_LENGTH_1024BIT}, + {YACA_KEY_TYPE_DSA_PRIV, + YACA_KEY_LENGTH_1024BIT, + YACA_KEY_LENGTH_1024BIT}, + {YACA_KEY_TYPE_EC_PRIV, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_EC_PRIME256V1, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_EC_PRIME256V1}, + {YACA_KEY_TYPE_DH_PRIV, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_DH_RFC_1024_160, + YACA_KEY_LENGTH_1024BIT} + }; + + for (const auto &pa: pargs) { + int ret; + yaca_key_h key = YACA_KEY_NULL; + + ret = yaca_key_generate(pa.type, pa.len, &key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + import_export(key, pa.type, pa.expected, PASSWORD, + YACA_KEY_FORMAT_PKCS8, YACA_KEY_FILE_FORMAT_DER); + + import_export(key, pa.type, pa.expected, PASSWORD, + YACA_KEY_FORMAT_PKCS8, YACA_KEY_FILE_FORMAT_PEM); + + yaca_key_destroy(key); + } +} + +BOOST_FIXTURE_TEST_CASE(T212__negative__key_import_export_encrypted, InitDebugFixture) +{ + static const char *PASSWORD = "ExamplE_PassworD"; + static const char *WRONG_PASSWORD = "wRONg_pASSWORd"; + + int ret; + yaca_key_h key_prv = YACA_KEY_NULL, key_pub; + yaca_key_h key_params = YACA_KEY_NULL, key_import = YACA_KEY_NULL; + + char *data_pem = NULL, *data_pkcs8_pem = NULL, *data_pkcs8_der = NULL; + size_t data_pem_len, data_pkcs8_pem_len, data_pkcs8_der_len; + + generate_asymmetric_keys(YACA_KEY_TYPE_DSA_PRIV, YACA_KEY_LENGTH_1024BIT, &key_prv, &key_pub, &key_params); + + ret = yaca_key_export(key_pub, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_PEM, + PASSWORD, &data_pem, &data_pem_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_export(key_params, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_PEM, + PASSWORD, &data_pem, &data_pem_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_export(key_pub, YACA_KEY_FORMAT_PKCS8, YACA_KEY_FILE_FORMAT_PEM, + PASSWORD, &data_pkcs8_pem, &data_pkcs8_pem_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_export(key_params, YACA_KEY_FORMAT_PKCS8, YACA_KEY_FILE_FORMAT_DER, + PASSWORD, &data_pkcs8_der, &data_pkcs8_der_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_export(key_prv, YACA_KEY_FORMAT_PKCS8, YACA_KEY_FILE_FORMAT_PEM, + NULL, &data_pkcs8_pem, &data_pkcs8_pem_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_export(key_prv, YACA_KEY_FORMAT_PKCS8, YACA_INVALID_KEY_FILE_FORMAT, + PASSWORD, &data_pkcs8_pem, &data_pkcs8_pem_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_export(key_prv, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_PEM, + PASSWORD, &data_pem, &data_pem_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_export(key_prv, YACA_KEY_FORMAT_PKCS8, YACA_KEY_FILE_FORMAT_PEM, + PASSWORD, &data_pkcs8_pem, &data_pkcs8_pem_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_export(key_prv, YACA_KEY_FORMAT_PKCS8, YACA_KEY_FILE_FORMAT_DER, + PASSWORD, &data_pkcs8_der, &data_pkcs8_der_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PUB, PASSWORD, + data_pem, data_pem_len, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PRIV, NULL, + data_pem, data_pem_len, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PASSWORD); + + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PRIV, WRONG_PASSWORD, + data_pem, data_pem_len, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PASSWORD); + + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PRIV, PASSWORD, + data_pem, data_pem_len - 2, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PRIV, PASSWORD, + data_pem + 1, data_pem_len - 1, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + data_pem[30] = (data_pem[30] == 'a' ? 'z' : 'a'); + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PRIV, PASSWORD, + data_pem, data_pem_len, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PUB, PASSWORD, + data_pkcs8_pem, data_pkcs8_pem_len, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PRIV, NULL, + data_pkcs8_pem, data_pkcs8_pem_len, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PASSWORD); + + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PRIV, WRONG_PASSWORD, + data_pkcs8_pem, data_pkcs8_pem_len, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PASSWORD); + + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PRIV, PASSWORD, + data_pkcs8_pem, data_pkcs8_pem_len - 2, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PRIV, PASSWORD, + data_pkcs8_pem + 1, data_pkcs8_pem_len - 1, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + data_pkcs8_pem[30] = (data_pkcs8_pem[30] == 'a' ? 'z' : 'a'); + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PRIV, PASSWORD, + data_pkcs8_pem, data_pkcs8_pem_len, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PARAMS, PASSWORD, + data_pkcs8_der, data_pkcs8_der_len, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PRIV, NULL, + data_pkcs8_der, data_pkcs8_der_len, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PASSWORD); + + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PRIV, WRONG_PASSWORD, + data_pkcs8_der, data_pkcs8_der_len, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PASSWORD); + + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PRIV, PASSWORD, + data_pkcs8_der, data_pkcs8_der_len - 1, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PRIV, PASSWORD, + data_pkcs8_der+ 1, data_pkcs8_der_len - 1, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + data_pkcs8_der[0] = ~data_pkcs8_der[0]; + data_pkcs8_der[1] = ~data_pkcs8_der[1]; + ret = yaca_key_import(YACA_KEY_TYPE_DSA_PRIV, PASSWORD, + data_pkcs8_der, data_pkcs8_der_len, &key_import); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_key_destroy(key_prv); + yaca_key_destroy(key_pub); + yaca_key_destroy(key_params); + yaca_free(data_pem); + yaca_free(data_pkcs8_pem); + yaca_free(data_pkcs8_der); +} + +BOOST_FIXTURE_TEST_CASE(T213__positive__key_derive_dh, InitDebugFixture) +{ + struct key_args { + yaca_key_type_e type; + yaca_key_bit_length_e len; + }; + + const std::vector kargs = { + {YACA_KEY_TYPE_DH_PRIV, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_DH_RFC_1024_160}, + {YACA_KEY_TYPE_EC_PRIV, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_EC_SECP384R1} + }; + + for (const auto &ka: kargs) { + int ret; + yaca_key_h priv1 = YACA_KEY_NULL, pub1 = YACA_KEY_NULL; + yaca_key_h priv2 = YACA_KEY_NULL, pub2 = YACA_KEY_NULL; + char *secret1 = NULL, *secret2 = NULL; + size_t secret1_len, secret2_len; + + generate_asymmetric_keys(ka.type, ka.len, &priv1, &pub1); + generate_asymmetric_keys(ka.type, ka.len, &priv2, &pub2); + + ret = yaca_key_derive_dh(priv1, pub2, &secret1, &secret1_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_derive_dh(priv2, pub1, &secret2, &secret2_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + BOOST_REQUIRE(secret1_len == secret2_len); + ret = yaca_memcmp(secret1, secret2, secret1_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_key_destroy(priv1); + yaca_key_destroy(priv2); + yaca_key_destroy(pub1); + yaca_key_destroy(pub2); + yaca_free(secret1); + yaca_free(secret2); + } +} + +BOOST_FIXTURE_TEST_CASE(T214__negative__key_derive_dh, InitDebugFixture) +{ + int ret; + yaca_key_h priv1 = YACA_KEY_NULL, pub1 = YACA_KEY_NULL; + yaca_key_h priv2 = YACA_KEY_NULL, pub2 = YACA_KEY_NULL; + char *secret = NULL; + size_t secret_len; + + generate_asymmetric_keys(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_1024BIT, &priv1, &pub1); + generate_asymmetric_keys(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_1024BIT, &priv2, &pub2); + + ret = yaca_key_derive_dh(YACA_KEY_NULL, pub2, &secret, &secret_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_derive_dh(pub1, pub2, &secret, &secret_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_derive_dh(priv1, YACA_KEY_NULL, &secret, &secret_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_derive_dh(priv1, priv2, &secret, &secret_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_derive_dh(priv1, pub2, NULL, &secret_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_derive_dh(priv1, pub2, &secret, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_key_destroy(priv1); + yaca_key_destroy(priv2); + yaca_key_destroy(pub1); + yaca_key_destroy(pub2); +} + +BOOST_FIXTURE_TEST_CASE(T215__positive__key_derive_kdf, InitDebugFixture) +{ + static const size_t SECRET_LEN = 128; + static const size_t MATERIAL_LEN = 256; + + struct kdf_args { + yaca_kdf_e kdf; + yaca_digest_algorithm_e digest; + }; + + const std::vector kargs = { + {YACA_KDF_X942, YACA_DIGEST_MD5}, + {YACA_KDF_X942, YACA_DIGEST_SHA1}, + {YACA_KDF_X942, YACA_DIGEST_SHA384}, + {YACA_KDF_X962, YACA_DIGEST_MD5}, + {YACA_KDF_X942, YACA_DIGEST_SHA1}, + {YACA_KDF_X942, YACA_DIGEST_SHA256} + }; + + int ret; + char secret[SECRET_LEN]; + + ret = yaca_randomize_bytes(secret, SECRET_LEN); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + for (const auto &ka: kargs) { + char *key_material1 = NULL, *key_material2 = NULL; + + ret = yaca_key_derive_kdf(ka.kdf, ka.digest, secret, SECRET_LEN, + NULL, 0, MATERIAL_LEN, &key_material1); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_derive_kdf(ka.kdf, ka.digest, secret, SECRET_LEN, + NULL, 0, MATERIAL_LEN, &key_material2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_memcmp(key_material1, key_material2, MATERIAL_LEN); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_free(key_material1); + yaca_free(key_material2); + } +} + +BOOST_FIXTURE_TEST_CASE(T216__negative__key_derive_kdf, InitDebugFixture) +{ + static const size_t SECRET_LEN = 128; + static const size_t MATERIAL_LEN = 256; + + int ret; + char secret[SECRET_LEN]; + char *key_material = NULL; + + ret = yaca_randomize_bytes(secret, SECRET_LEN); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_key_derive_kdf(YACA_INVALID_KDF, YACA_DIGEST_MD5, secret, SECRET_LEN, + NULL, 0, MATERIAL_LEN, &key_material); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_derive_kdf(YACA_KDF_X942, YACA_INVALID_DIGEST_ALGORITHM, secret, SECRET_LEN, + NULL, 0, MATERIAL_LEN, &key_material); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_derive_kdf(YACA_KDF_X942, YACA_DIGEST_MD5, NULL, SECRET_LEN, + NULL, 0, MATERIAL_LEN, &key_material); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_derive_kdf(YACA_KDF_X942, YACA_DIGEST_MD5, secret, 0, + NULL, 0, MATERIAL_LEN, &key_material); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_derive_kdf(YACA_KDF_X942, YACA_DIGEST_MD5, secret, SECRET_LEN, + "test", 0, MATERIAL_LEN, &key_material); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_derive_kdf(YACA_KDF_X942, YACA_DIGEST_MD5, secret, SECRET_LEN, + NULL, 10, MATERIAL_LEN, &key_material); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_derive_kdf(YACA_KDF_X942, YACA_DIGEST_MD5, secret, SECRET_LEN, + NULL, 0, 0, &key_material); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_derive_kdf(YACA_KDF_X942, YACA_DIGEST_MD5, secret, SECRET_LEN, + NULL, 0, MATERIAL_LEN, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); +} + +BOOST_FIXTURE_TEST_CASE(T217__positive__key_derive_pbkdf2, InitDebugFixture) +{ + static const char *PASSWORD = "Password_ExamplE"; + static const size_t SALT_LEN = 64; + + struct pbkdf2_args { + yaca_digest_algorithm_e digest; + size_t iter; + size_t bit_len; + }; + + const std::vector pargs = { + {YACA_DIGEST_MD5, 1, 256}, + {YACA_DIGEST_SHA256, 10, 256}, + {YACA_DIGEST_SHA1, 15, 512}, + {YACA_DIGEST_SHA224, 33, 128}, + {YACA_DIGEST_SHA512, 50, 512} + }; + + int ret; + char salt[SALT_LEN]; + + ret = yaca_randomize_bytes(salt, SALT_LEN); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + for (const auto &pa: pargs) { + yaca_key_h key1 = YACA_KEY_NULL, key2 = YACA_KEY_NULL; + yaca_key_type_e type; + size_t len; + + ret = yaca_key_derive_pbkdf2(PASSWORD, salt, SALT_LEN, pa.iter, + pa.digest, pa.bit_len, &key1); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_derive_pbkdf2(PASSWORD, salt, SALT_LEN, pa.iter, + pa.digest, pa.bit_len, &key2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_key_get_type(key1, &type); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + BOOST_REQUIRE(type == YACA_KEY_TYPE_SYMMETRIC); + ret = yaca_key_get_bit_length(key1, &len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + BOOST_REQUIRE(len == pa.bit_len); + + ret = yaca_key_get_type(key2, &type); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + BOOST_REQUIRE(type == YACA_KEY_TYPE_SYMMETRIC); + ret = yaca_key_get_bit_length(key2, &len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + BOOST_REQUIRE(len == pa.bit_len); + + assert_keys_identical(key1, key2); + + yaca_key_destroy(key1); + yaca_key_destroy(key2); + } +} + +BOOST_FIXTURE_TEST_CASE(T218__negative__key_derive_pbkdf2, InitDebugFixture) +{ + static const char *PASSWORD = "Password_ExamplE"; + static const size_t SALT_LEN = 64; + + int ret; + char salt[SALT_LEN]; + yaca_key_h key = YACA_KEY_NULL; + + ret = yaca_randomize_bytes(salt, SALT_LEN); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_key_derive_pbkdf2(NULL, salt, SALT_LEN, 10, + YACA_DIGEST_SHA1, YACA_KEY_LENGTH_256BIT, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_derive_pbkdf2(PASSWORD, NULL, SALT_LEN, 10, + YACA_DIGEST_SHA1, YACA_KEY_LENGTH_256BIT, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_derive_pbkdf2(PASSWORD, salt, 0, 10, + YACA_DIGEST_SHA1, YACA_KEY_LENGTH_256BIT, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_derive_pbkdf2(PASSWORD, salt, SALT_LEN, 0, + YACA_DIGEST_SHA1, YACA_KEY_LENGTH_256BIT, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_derive_pbkdf2(PASSWORD, salt, SALT_LEN, INT_MAX + 1UL, + YACA_DIGEST_SHA1, YACA_KEY_LENGTH_256BIT, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_derive_pbkdf2(PASSWORD, salt, SALT_LEN, 10, + YACA_INVALID_DIGEST_ALGORITHM, YACA_KEY_LENGTH_256BIT, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_derive_pbkdf2(PASSWORD, salt, SALT_LEN, 10, + YACA_DIGEST_SHA1, 0, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_derive_pbkdf2(PASSWORD, salt, SALT_LEN, 10, + YACA_DIGEST_SHA1, 1, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_derive_pbkdf2(PASSWORD, salt, SALT_LEN, 10, + YACA_DIGEST_SHA1, 127, &key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_derive_pbkdf2(PASSWORD, salt, SALT_LEN, 10, + YACA_DIGEST_SHA1, YACA_KEY_LENGTH_256BIT, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); +} + +BOOST_FIXTURE_TEST_CASE(T219__positive__import_x509_cert, InitDebugFixture) +{ + static const char data_pem[] = "-----BEGIN CERTIFICATE-----\n\ +MIIC9jCCAl+gAwIBAgIUaWM7DVy/evvsrKz8gkz3qWZKw7EwDQYJKoZIhvcNAQEL\n\ +BQAwgYwxCzAJBgNVBAYTAlBMMRQwEgYDVQQIDAtNYXpvd2llY2tpZTERMA8GA1UE\n\ +BwwIV2Fyc3phd2ExEDAOBgNVBAoMB1NhbXN1bmcxCzAJBgNVBAsMAklUMRQwEgYD\n\ +VQQDDAtzYW1zdW5nLmNvbTEfMB0GCSqGSIb3DQEJARYQbm9uZUBzYW1zdW5nLmNv\n\ +bTAeFw0yMDA0MDkxNzUzMDlaFw0yNTA0MDgxNzUzMDlaMIGMMQswCQYDVQQGEwJQ\n\ +TDEUMBIGA1UECAwLTWF6b3dpZWNraWUxETAPBgNVBAcMCFdhcnN6YXdhMRAwDgYD\n\ +VQQKDAdTYW1zdW5nMQswCQYDVQQLDAJJVDEUMBIGA1UEAwwLc2Ftc3VuZy5jb20x\n\ +HzAdBgkqhkiG9w0BCQEWEG5vbmVAc2Ftc3VuZy5jb20wgZ8wDQYJKoZIhvcNAQEB\n\ +BQADgY0AMIGJAoGBAMrx4VdcBEWSXdOa7nJr6Vh53TDfnqhgOGRUC8c+kGUu45Cp\n\ +hcGU7q44zfqvEdgkVBK+Y6GBMrbB0TALo2zK4RVDIgTc8UskbiBjiP4cHB+Zl460\n\ +kU/0vKZPWt7yWq9g87lppEr/f0RTGrKkkcVadCxmKILr4ZtS9563xXH+kKAlAgMB\n\ +AAGjUzBRMB0GA1UdDgQWBBQBroKxSi+l6RqOD5jQGRYyoM0I1jAfBgNVHSMEGDAW\n\ +gBQBroKxSi+l6RqOD5jQGRYyoM0I1jAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3\n\ +DQEBCwUAA4GBAC1f+n4ly876nTXMjdINH8qmxrHOH55vt7v1KYWqCVFSJbqtQMlT\n\ +E9+bqRGN2LpzMBkDdNkGSrCesI1l/FUStjqdpBGMi1fqFDNDyBXkLJDH5HAMR3ei\n\ +hajHIasdGWcAfj+Cyuk1KcTIEkBfdYR6a8C4g04Vbg6M0qEjFl5UTMwm\n\ +-----END CERTIFICATE-----"; + + /* THIS CHUNK OF BYTES IS AUTOMATICALLY GENERATED */ + static const unsigned char data_der[] = { + 0x30, 0x82, 0x02, 0xf6, 0x30, 0x82, 0x02, 0x5f, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x69, + 0x63, 0x3b, 0x0d, 0x5c, 0xbf, 0x7a, 0xfb, 0xec, 0xac, 0xac, 0xfc, 0x82, 0x4c, 0xf7, 0xa9, 0x66, + 0x4a, 0xc3, 0xb1, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x05, 0x00, 0x30, 0x81, 0x8c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x50, 0x4c, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0b, 0x4d, 0x61, 0x7a, + 0x6f, 0x77, 0x69, 0x65, 0x63, 0x6b, 0x69, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0c, 0x08, 0x57, 0x61, 0x72, 0x73, 0x7a, 0x61, 0x77, 0x61, 0x31, 0x10, 0x30, 0x0e, 0x06, + 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x53, 0x61, 0x6d, 0x73, 0x75, 0x6e, 0x67, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x02, 0x49, 0x54, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0c, 0x0b, 0x73, 0x61, 0x6d, 0x73, 0x75, 0x6e, 0x67, 0x2e, 0x63, 0x6f, 0x6d, + 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, + 0x10, 0x6e, 0x6f, 0x6e, 0x65, 0x40, 0x73, 0x61, 0x6d, 0x73, 0x75, 0x6e, 0x67, 0x2e, 0x63, 0x6f, + 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x30, 0x30, 0x34, 0x30, 0x39, 0x31, 0x37, 0x35, 0x33, 0x30, + 0x39, 0x5a, 0x17, 0x0d, 0x32, 0x35, 0x30, 0x34, 0x30, 0x38, 0x31, 0x37, 0x35, 0x33, 0x30, 0x39, + 0x5a, 0x30, 0x81, 0x8c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x50, + 0x4c, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0b, 0x4d, 0x61, 0x7a, 0x6f, + 0x77, 0x69, 0x65, 0x63, 0x6b, 0x69, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0c, 0x08, 0x57, 0x61, 0x72, 0x73, 0x7a, 0x61, 0x77, 0x61, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x53, 0x61, 0x6d, 0x73, 0x75, 0x6e, 0x67, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x02, 0x49, 0x54, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0c, 0x0b, 0x73, 0x61, 0x6d, 0x73, 0x75, 0x6e, 0x67, 0x2e, 0x63, 0x6f, 0x6d, 0x31, + 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, + 0x6e, 0x6f, 0x6e, 0x65, 0x40, 0x73, 0x61, 0x6d, 0x73, 0x75, 0x6e, 0x67, 0x2e, 0x63, 0x6f, 0x6d, + 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, + 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xca, 0xf1, 0xe1, + 0x57, 0x5c, 0x04, 0x45, 0x92, 0x5d, 0xd3, 0x9a, 0xee, 0x72, 0x6b, 0xe9, 0x58, 0x79, 0xdd, 0x30, + 0xdf, 0x9e, 0xa8, 0x60, 0x38, 0x64, 0x54, 0x0b, 0xc7, 0x3e, 0x90, 0x65, 0x2e, 0xe3, 0x90, 0xa9, + 0x85, 0xc1, 0x94, 0xee, 0xae, 0x38, 0xcd, 0xfa, 0xaf, 0x11, 0xd8, 0x24, 0x54, 0x12, 0xbe, 0x63, + 0xa1, 0x81, 0x32, 0xb6, 0xc1, 0xd1, 0x30, 0x0b, 0xa3, 0x6c, 0xca, 0xe1, 0x15, 0x43, 0x22, 0x04, + 0xdc, 0xf1, 0x4b, 0x24, 0x6e, 0x20, 0x63, 0x88, 0xfe, 0x1c, 0x1c, 0x1f, 0x99, 0x97, 0x8e, 0xb4, + 0x91, 0x4f, 0xf4, 0xbc, 0xa6, 0x4f, 0x5a, 0xde, 0xf2, 0x5a, 0xaf, 0x60, 0xf3, 0xb9, 0x69, 0xa4, + 0x4a, 0xff, 0x7f, 0x44, 0x53, 0x1a, 0xb2, 0xa4, 0x91, 0xc5, 0x5a, 0x74, 0x2c, 0x66, 0x28, 0x82, + 0xeb, 0xe1, 0x9b, 0x52, 0xf7, 0x9e, 0xb7, 0xc5, 0x71, 0xfe, 0x90, 0xa0, 0x25, 0x02, 0x03, 0x01, + 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, + 0x14, 0x01, 0xae, 0x82, 0xb1, 0x4a, 0x2f, 0xa5, 0xe9, 0x1a, 0x8e, 0x0f, 0x98, 0xd0, 0x19, 0x16, + 0x32, 0xa0, 0xcd, 0x08, 0xd6, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, + 0x80, 0x14, 0x01, 0xae, 0x82, 0xb1, 0x4a, 0x2f, 0xa5, 0xe9, 0x1a, 0x8e, 0x0f, 0x98, 0xd0, 0x19, + 0x16, 0x32, 0xa0, 0xcd, 0x08, 0xd6, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, + 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x2d, 0x5f, 0xfa, 0x7e, 0x25, 0xcb, + 0xce, 0xfa, 0x9d, 0x35, 0xcc, 0x8d, 0xd2, 0x0d, 0x1f, 0xca, 0xa6, 0xc6, 0xb1, 0xce, 0x1f, 0x9e, + 0x6f, 0xb7, 0xbb, 0xf5, 0x29, 0x85, 0xaa, 0x09, 0x51, 0x52, 0x25, 0xba, 0xad, 0x40, 0xc9, 0x53, + 0x13, 0xdf, 0x9b, 0xa9, 0x11, 0x8d, 0xd8, 0xba, 0x73, 0x30, 0x19, 0x03, 0x74, 0xd9, 0x06, 0x4a, + 0xb0, 0x9e, 0xb0, 0x8d, 0x65, 0xfc, 0x55, 0x12, 0xb6, 0x3a, 0x9d, 0xa4, 0x11, 0x8c, 0x8b, 0x57, + 0xea, 0x14, 0x33, 0x43, 0xc8, 0x15, 0xe4, 0x2c, 0x90, 0xc7, 0xe4, 0x70, 0x0c, 0x47, 0x77, 0xa2, + 0x85, 0xa8, 0xc7, 0x21, 0xab, 0x1d, 0x19, 0x67, 0x00, 0x7e, 0x3f, 0x82, 0xca, 0xe9, 0x35, 0x29, + 0xc4, 0xc8, 0x12, 0x40, 0x5f, 0x75, 0x84, 0x7a, 0x6b, 0xc0, 0xb8, 0x83, 0x4e, 0x15, 0x6e, 0x0e, + 0x8c, 0xd2, 0xa1, 0x23, 0x16, 0x5e, 0x54, 0x4c, 0xcc, 0x26 + }; + + int ret; + yaca_key_h key_pem = YACA_KEY_NULL, key_der = YACA_KEY_NULL; + yaca_key_type_e type; + size_t len; + + ret = yaca_key_import(YACA_KEY_TYPE_RSA_PUB, NULL, data_pem, + sizeof(data_pem), &key_pem); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_key_get_type(key_pem, &type); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + BOOST_REQUIRE(type == YACA_KEY_TYPE_RSA_PUB); + + ret = yaca_key_get_bit_length(key_pem, &len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + BOOST_REQUIRE(len == YACA_KEY_LENGTH_1024BIT); + + ret = yaca_key_import(YACA_KEY_TYPE_RSA_PUB, NULL, (char*)data_der, + sizeof(data_der), &key_der); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_key_get_type(key_der, &type); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + BOOST_REQUIRE(type == YACA_KEY_TYPE_RSA_PUB); + + ret = yaca_key_get_bit_length(key_der, &len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + BOOST_REQUIRE(len == YACA_KEY_LENGTH_1024BIT); + + assert_keys_identical(key_pem, key_der); + + yaca_key_destroy(key_pem); + yaca_key_destroy(key_der); +} + +BOOST_FIXTURE_TEST_CASE(T220__negative__key_get, InitDebugFixture) +{ + int ret; + yaca_key_h key = YACA_KEY_NULL; + yaca_key_type_e type; + size_t len; + + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_256BIT, &key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_key_get_type(YACA_KEY_NULL, &type); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_get_bit_length(YACA_KEY_NULL, &len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_get_type(key, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_key_get_bit_length(key, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_key_destroy(key); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/test_rsa.cpp b/tests/test_rsa.cpp new file mode 100644 index 0000000..0f9e095 --- /dev/null +++ b/tests/test_rsa.cpp @@ -0,0 +1,598 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Pawelczyk + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file test_rsa.c + * @author Lukasz Pawelczyk + * @brief RSA API unit tests. + */ + +#include +#include + +#include +#include +#include +#include + +#include "common.h" + + +BOOST_AUTO_TEST_SUITE(TESTS_RSA) + +BOOST_FIXTURE_TEST_CASE(T401__positive__private_encrypt, InitDebugFixture) +{ + struct rsa_args { + yaca_padding_e pad; + yaca_key_bit_length_e bit_len; + size_t shorter; + }; + + const std::vector rargs = { + {YACA_PADDING_NONE, YACA_KEY_LENGTH_512BIT, 0}, + {YACA_PADDING_NONE, YACA_KEY_LENGTH_2048BIT, 0}, + {YACA_PADDING_PKCS1, YACA_KEY_LENGTH_512BIT, 11}, + {YACA_PADDING_PKCS1, YACA_KEY_LENGTH_4096BIT, 11}, + }; + + for (const auto &ra: rargs) { + int ret; + yaca_key_h rsa_prv = YACA_KEY_NULL, rsa_pub = YACA_KEY_NULL; + size_t input_len = ra.bit_len / 8 - ra.shorter; + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len, decrypted_len; + + generate_asymmetric_keys(YACA_KEY_TYPE_RSA_PRIV, ra.bit_len, &rsa_prv, &rsa_pub); + + ret = yaca_rsa_private_encrypt(ra.pad, rsa_prv, INPUT_DATA, input_len, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_rsa_public_decrypt(ra.pad, rsa_pub, encrypted, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + BOOST_REQUIRE(decrypted_len == input_len); + ret = yaca_memcmp(decrypted, INPUT_DATA, input_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_key_destroy(rsa_prv); + yaca_key_destroy(rsa_pub); + yaca_free(encrypted); + yaca_free(decrypted); + } + + /* Empty input, must use padding */ + for (const auto &ra: rargs) { + if (ra.pad == YACA_PADDING_NONE) + continue; + + int ret; + yaca_key_h rsa_prv = YACA_KEY_NULL, rsa_pub = YACA_KEY_NULL; + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len, decrypted_len; + + generate_asymmetric_keys(YACA_KEY_TYPE_RSA_PRIV, ra.bit_len, &rsa_prv, &rsa_pub); + + ret = yaca_rsa_private_encrypt(ra.pad, rsa_prv, NULL, 0, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_rsa_public_decrypt(ra.pad, rsa_pub, encrypted, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + BOOST_REQUIRE(decrypted == NULL); + BOOST_REQUIRE(decrypted_len == 0); + + yaca_key_destroy(rsa_prv); + yaca_key_destroy(rsa_pub); + yaca_free(encrypted); + yaca_free(decrypted); + } +} + +BOOST_FIXTURE_TEST_CASE(T402__negative__private_encrypt, InitDebugFixture) +{ + int ret; + size_t bit_len = YACA_KEY_LENGTH_1024BIT; + yaca_key_h key_prv = YACA_KEY_NULL, key_pub = YACA_KEY_NULL; + yaca_key_h key_prv2 = YACA_KEY_NULL, key_pub2 = YACA_KEY_NULL; + yaca_key_h key_dsa = YACA_KEY_NULL, key_ec = YACA_KEY_NULL; + size_t input_len = bit_len / 8; + size_t input_len_pkcs1 = bit_len / 8 - 11; + char *encrypted = NULL, *encrypted_pkcs1 = NULL, *decrypted = NULL; + size_t encrypted_len, encrypted_pkcs1_len, decrypted_len; + + generate_asymmetric_keys(YACA_KEY_TYPE_RSA_PRIV, bit_len, &key_prv, &key_pub); + generate_asymmetric_keys(YACA_KEY_TYPE_RSA_PRIV, bit_len, &key_prv2, &key_pub2); + generate_asymmetric_keys(YACA_KEY_TYPE_DSA_PRIV, bit_len, &key_dsa); + generate_asymmetric_keys(YACA_KEY_TYPE_EC_PRIV, YACA_KEY_LENGTH_EC_PRIME256V1, &key_ec); + + ret = yaca_rsa_private_encrypt(YACA_INVALID_PADDING, key_prv, + INPUT_DATA, input_len, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_encrypt(YACA_PADDING_X931, key_prv, + INPUT_DATA, input_len, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_encrypt(YACA_PADDING_PKCS1_OAEP, key_prv, + INPUT_DATA, input_len, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_encrypt(YACA_PADDING_NONE, YACA_KEY_NULL, + INPUT_DATA, input_len, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_encrypt(YACA_PADDING_NONE, key_pub, + INPUT_DATA, input_len, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_encrypt(YACA_PADDING_NONE, key_ec, + INPUT_DATA, input_len, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_encrypt(YACA_PADDING_NONE, key_dsa, + INPUT_DATA, input_len, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_encrypt(YACA_PADDING_NONE, key_prv, + NULL, input_len, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_encrypt(YACA_PADDING_NONE, key_prv, + INPUT_DATA, 0, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_encrypt(YACA_PADDING_NONE, key_prv, + INPUT_DATA, input_len + 1, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_encrypt(YACA_PADDING_NONE, key_prv, + INPUT_DATA, input_len - 1, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_encrypt(YACA_PADDING_NONE, key_prv, + INPUT_DATA, input_len - 8, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_encrypt(YACA_PADDING_NONE, key_prv, + INPUT_DATA, input_len, + NULL, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_encrypt(YACA_PADDING_NONE, key_prv, + INPUT_DATA, input_len, + &encrypted, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_encrypt(YACA_PADDING_PKCS1, key_prv, + INPUT_DATA, input_len_pkcs1 + 1, + &encrypted_pkcs1, &encrypted_pkcs1_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_encrypt(YACA_PADDING_NONE, key_prv, + INPUT_DATA, input_len, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_rsa_private_encrypt(YACA_PADDING_PKCS1, key_prv, + INPUT_DATA, input_len_pkcs1, + &encrypted_pkcs1, &encrypted_pkcs1_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_rsa_public_decrypt(YACA_INVALID_PADDING, key_pub, + encrypted, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_decrypt(YACA_PADDING_PKCS1_SSLV23, key_pub, + encrypted, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_decrypt(YACA_PADDING_PKCS1, key_pub, + encrypted, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_decrypt(YACA_PADDING_NONE, YACA_KEY_NULL, + encrypted, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_decrypt(YACA_PADDING_NONE, key_prv, + encrypted, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_decrypt(YACA_PADDING_NONE, key_ec, + encrypted, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_decrypt(YACA_PADDING_NONE, key_dsa, + encrypted, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_decrypt(YACA_PADDING_NONE, key_pub, + NULL, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_decrypt(YACA_PADDING_NONE, key_pub, + encrypted, 0, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_decrypt(YACA_PADDING_NONE, key_pub, + encrypted, encrypted_len, + NULL, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_decrypt(YACA_PADDING_NONE, key_pub, + encrypted, encrypted_len, + &decrypted, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_decrypt(YACA_PADDING_PKCS1_PSS, key_pub, + encrypted_pkcs1, encrypted_pkcs1_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_decrypt(YACA_PADDING_X931, key_pub, + encrypted_pkcs1, encrypted_pkcs1_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_decrypt(YACA_PADDING_PKCS1, key_pub2, + encrypted_pkcs1, encrypted_pkcs1_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_decrypt(YACA_PADDING_PKCS1, key_pub, + encrypted_pkcs1, encrypted_pkcs1_len - 1, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_decrypt(YACA_PADDING_PKCS1, key_pub, + encrypted_pkcs1 + 1, encrypted_pkcs1_len - 1, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_key_destroy(key_prv); + yaca_key_destroy(key_pub); + yaca_key_destroy(key_prv2); + yaca_key_destroy(key_pub2); + yaca_key_destroy(key_dsa); + yaca_key_destroy(key_ec); + yaca_free(encrypted); + yaca_free(encrypted_pkcs1); +} + +BOOST_FIXTURE_TEST_CASE(T403__positive__public_encrypt, InitDebugFixture) +{ + struct rsa_args { + yaca_padding_e pad; + yaca_key_bit_length_e bit_len; + size_t shorter; + }; + + const std::vector rargs = { + {YACA_PADDING_NONE, YACA_KEY_LENGTH_512BIT, 0}, + {YACA_PADDING_PKCS1, YACA_KEY_LENGTH_1024BIT, 11}, + {YACA_PADDING_PKCS1_OAEP, YACA_KEY_LENGTH_2048BIT, 42}, + }; + + for (const auto &ra: rargs) { + int ret; + yaca_key_h rsa_prv = YACA_KEY_NULL, rsa_pub = YACA_KEY_NULL; + size_t input_len = ra.bit_len / 8 - ra.shorter; + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len, decrypted_len; + + generate_asymmetric_keys(YACA_KEY_TYPE_RSA_PRIV, ra.bit_len, &rsa_prv, &rsa_pub); + + ret = yaca_rsa_public_encrypt(ra.pad, rsa_pub, INPUT_DATA, input_len, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_rsa_private_decrypt(ra.pad, rsa_prv, encrypted, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + BOOST_REQUIRE(decrypted_len == input_len); + ret = yaca_memcmp(decrypted, INPUT_DATA, input_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_key_destroy(rsa_prv); + yaca_key_destroy(rsa_pub); + yaca_free(encrypted); + yaca_free(decrypted); + } + + /* Empty input, must use padding */ + for (const auto &ra: rargs) { + if (ra.pad == YACA_PADDING_NONE) + continue; + + int ret; + yaca_key_h rsa_prv = YACA_KEY_NULL, rsa_pub = YACA_KEY_NULL; + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len, decrypted_len; + + generate_asymmetric_keys(YACA_KEY_TYPE_RSA_PRIV, ra.bit_len, &rsa_prv, &rsa_pub); + + ret = yaca_rsa_public_encrypt(ra.pad, rsa_pub, NULL, 0, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_rsa_private_decrypt(ra.pad, rsa_prv, encrypted, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + BOOST_REQUIRE(decrypted_len == 0); + BOOST_REQUIRE(decrypted == NULL); + + yaca_key_destroy(rsa_prv); + yaca_key_destroy(rsa_pub); + yaca_free(encrypted); + yaca_free(decrypted); + } +} + +BOOST_FIXTURE_TEST_CASE(T404__negative__public_encrypt, InitDebugFixture) +{ + int ret; + size_t bit_len = YACA_KEY_LENGTH_1024BIT; + yaca_key_h key_prv = YACA_KEY_NULL, key_pub = YACA_KEY_NULL; + yaca_key_h key_prv2 = YACA_KEY_NULL, key_pub2 = YACA_KEY_NULL; + yaca_key_h key_dsa = YACA_KEY_NULL, key_ec = YACA_KEY_NULL; + size_t input_len = bit_len / 8; + size_t input_len_pkcs1 = bit_len / 8 - 11; + size_t input_len_pkcs1_oaep = bit_len / 8 - 42; + size_t input_len_pkcs1_sslv23 = bit_len / 8 - 11; + char *encrypted = NULL, *encrypted_pkcs1 = NULL; + char *encrypted_pkcs1_oaep = NULL, *encrypted_pkcs1_sslv23 = NULL; + char *decrypted = NULL; + size_t encrypted_len, encrypted_pkcs1_len, encrypted_pkcs1_oaep_len; + size_t encrypted_pkcs1_sslv23_len, decrypted_len; + + generate_asymmetric_keys(YACA_KEY_TYPE_RSA_PRIV, bit_len, &key_prv, &key_pub); + generate_asymmetric_keys(YACA_KEY_TYPE_RSA_PRIV, bit_len, &key_prv2, &key_pub2); + generate_asymmetric_keys(YACA_KEY_TYPE_DSA_PRIV, bit_len, &key_dsa); + generate_asymmetric_keys(YACA_KEY_TYPE_EC_PRIV, YACA_KEY_LENGTH_EC_PRIME256V1, &key_ec); + + ret = yaca_rsa_public_encrypt(YACA_INVALID_PADDING, key_pub, + INPUT_DATA, input_len, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_encrypt(YACA_PADDING_X931, key_pub, + INPUT_DATA, input_len, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_encrypt(YACA_PADDING_PKCS1_PSS, key_pub, + INPUT_DATA, input_len, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_encrypt(YACA_PADDING_NONE, YACA_KEY_NULL, + INPUT_DATA, input_len, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_encrypt(YACA_PADDING_NONE, key_prv, + INPUT_DATA, input_len, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_encrypt(YACA_PADDING_NONE, key_ec, + INPUT_DATA, input_len, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_encrypt(YACA_PADDING_NONE, key_dsa, + INPUT_DATA, input_len, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_encrypt(YACA_PADDING_NONE, key_pub, + NULL, input_len, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_encrypt(YACA_PADDING_NONE, key_pub, + INPUT_DATA, 0, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_encrypt(YACA_PADDING_NONE, key_pub, + INPUT_DATA, input_len + 1, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_encrypt(YACA_PADDING_NONE, key_pub, + INPUT_DATA, input_len - 1, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_encrypt(YACA_PADDING_NONE, key_pub, + INPUT_DATA, input_len - 8, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_encrypt(YACA_PADDING_NONE, key_pub, + INPUT_DATA, input_len, + NULL, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_encrypt(YACA_PADDING_NONE, key_pub, + INPUT_DATA, input_len, + &encrypted, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_encrypt(YACA_PADDING_PKCS1, key_pub, + INPUT_DATA, input_len_pkcs1 + 1, + &encrypted_pkcs1, &encrypted_pkcs1_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_encrypt(YACA_PADDING_PKCS1_OAEP, key_pub, + INPUT_DATA, input_len_pkcs1_oaep + 1, + &encrypted_pkcs1_oaep, &encrypted_pkcs1_oaep_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_encrypt(YACA_PADDING_PKCS1_SSLV23, key_pub, + INPUT_DATA, input_len_pkcs1_sslv23 + 1, + &encrypted_pkcs1_sslv23, &encrypted_pkcs1_sslv23_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_encrypt(YACA_PADDING_NONE, key_pub, + INPUT_DATA, input_len, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_rsa_public_encrypt(YACA_PADDING_PKCS1, key_pub, + INPUT_DATA, input_len_pkcs1, + &encrypted_pkcs1, &encrypted_pkcs1_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_rsa_public_encrypt(YACA_PADDING_PKCS1_OAEP, key_pub, + INPUT_DATA, input_len_pkcs1_oaep, + &encrypted_pkcs1_oaep, &encrypted_pkcs1_oaep_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_rsa_public_encrypt(YACA_PADDING_PKCS1_SSLV23, key_pub, + INPUT_DATA, input_len_pkcs1_sslv23, + &encrypted_pkcs1_sslv23, &encrypted_pkcs1_sslv23_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_rsa_private_decrypt(YACA_INVALID_PADDING, key_prv, + encrypted, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_decrypt(YACA_PADDING_X931, key_prv, + encrypted, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_decrypt(YACA_PADDING_PKCS1, key_prv, + encrypted, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_decrypt(YACA_PADDING_NONE, YACA_KEY_NULL, + encrypted, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_decrypt(YACA_PADDING_NONE, key_pub, + encrypted, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_decrypt(YACA_PADDING_NONE, key_ec, + encrypted, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_decrypt(YACA_PADDING_NONE, key_dsa, + encrypted, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_decrypt(YACA_PADDING_NONE, key_prv, + NULL, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_decrypt(YACA_PADDING_NONE, key_prv, + encrypted, 0, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_decrypt(YACA_PADDING_NONE, key_prv, + encrypted, encrypted_len, + NULL, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_decrypt(YACA_PADDING_NONE, key_prv, + encrypted, encrypted_len, + &decrypted, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_decrypt(YACA_PADDING_PKCS1_PSS, key_prv, + encrypted_pkcs1, encrypted_pkcs1_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_decrypt(YACA_PADDING_PKCS1, key_prv, + encrypted_pkcs1, encrypted_pkcs1_len - 1, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_decrypt(YACA_PADDING_PKCS1, key_prv, + encrypted_pkcs1_oaep, encrypted_pkcs1_oaep_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_decrypt(YACA_PADDING_PKCS1_SSLV23, key_prv, + encrypted_pkcs1_oaep, encrypted_pkcs1_oaep_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_decrypt(YACA_PADDING_PKCS1_OAEP, key_prv, + encrypted_pkcs1_oaep, encrypted_pkcs1_oaep_len - 1, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_decrypt(YACA_PADDING_PKCS1_OAEP, key_prv, + encrypted_pkcs1_sslv23, encrypted_pkcs1_sslv23_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_private_decrypt(YACA_PADDING_PKCS1_SSLV23, key_prv, + encrypted_pkcs1_sslv23, encrypted_pkcs1_sslv23_len - 1, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_key_destroy(key_prv); + yaca_key_destroy(key_pub); + yaca_key_destroy(key_prv2); + yaca_key_destroy(key_pub2); + yaca_key_destroy(key_dsa); + yaca_key_destroy(key_ec); + yaca_free(encrypted); + yaca_free(encrypted_pkcs1); + yaca_free(encrypted_pkcs1_oaep); + yaca_free(encrypted_pkcs1_sslv23); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/test_seal.cpp b/tests/test_seal.cpp new file mode 100644 index 0000000..63f78b2 --- /dev/null +++ b/tests/test_seal.cpp @@ -0,0 +1,1683 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Pawelczyk + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file test_seal.cpp + * @author Lukasz Pawelczyk + * @brief Seal API unit tests. + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "common.h" + + +BOOST_AUTO_TEST_SUITE(TESTS_SEAL) + +BOOST_FIXTURE_TEST_CASE(T701__positive__seal_open, InitDebugFixture) +{ + struct seal_args { + yaca_encrypt_algorithm_e algo; + yaca_block_cipher_mode_e bcm; + size_t key_bit_len; + yaca_padding_e padding; + size_t split; + }; + + const std::vector sargs = { + {YACA_ENCRYPT_AES, YACA_BCM_CBC, 128, YACA_INVALID_PADDING, 16}, + {YACA_ENCRYPT_AES, YACA_BCM_CBC, 128, YACA_PADDING_NONE, 8}, + {YACA_ENCRYPT_AES, YACA_BCM_CBC, 128, YACA_PADDING_PKCS7, 11}, + {YACA_ENCRYPT_AES, YACA_BCM_CFB, 128, YACA_INVALID_PADDING, 24}, + {YACA_ENCRYPT_AES, YACA_BCM_CFB1, 128, YACA_INVALID_PADDING, 13}, + {YACA_ENCRYPT_AES, YACA_BCM_CFB8, 128, YACA_INVALID_PADDING, 4}, + {YACA_ENCRYPT_AES, YACA_BCM_CTR, 128, YACA_INVALID_PADDING, 66}, + {YACA_ENCRYPT_AES, YACA_BCM_ECB, 128, YACA_INVALID_PADDING, 3}, + {YACA_ENCRYPT_AES, YACA_BCM_ECB, 128, YACA_PADDING_NONE, 11}, + {YACA_ENCRYPT_AES, YACA_BCM_ECB, 128, YACA_PADDING_PKCS7, 34}, + {YACA_ENCRYPT_AES, YACA_BCM_OFB, 128, YACA_INVALID_PADDING, 27}, + + {YACA_ENCRYPT_AES, YACA_BCM_CBC, 192, YACA_INVALID_PADDING, 9}, + {YACA_ENCRYPT_AES, YACA_BCM_CBC, 192, YACA_PADDING_NONE, 12}, + {YACA_ENCRYPT_AES, YACA_BCM_CBC, 192, YACA_PADDING_PKCS7, 11}, + {YACA_ENCRYPT_AES, YACA_BCM_CFB, 192, YACA_INVALID_PADDING, 31}, + {YACA_ENCRYPT_AES, YACA_BCM_CFB1, 192, YACA_INVALID_PADDING, 17}, + {YACA_ENCRYPT_AES, YACA_BCM_CFB8, 192, YACA_INVALID_PADDING, 2}, + {YACA_ENCRYPT_AES, YACA_BCM_CTR, 192, YACA_INVALID_PADDING, 1}, + {YACA_ENCRYPT_AES, YACA_BCM_ECB, 192, YACA_INVALID_PADDING, 24}, + {YACA_ENCRYPT_AES, YACA_BCM_ECB, 192, YACA_PADDING_NONE, 15}, + {YACA_ENCRYPT_AES, YACA_BCM_ECB, 192, YACA_PADDING_PKCS7, 33}, + {YACA_ENCRYPT_AES, YACA_BCM_OFB, 192, YACA_INVALID_PADDING, 44}, + + {YACA_ENCRYPT_AES, YACA_BCM_CBC, 256, YACA_INVALID_PADDING, 10}, + {YACA_ENCRYPT_AES, YACA_BCM_CBC, 256, YACA_PADDING_NONE, 11}, + {YACA_ENCRYPT_AES, YACA_BCM_CBC, 256, YACA_PADDING_PKCS7, 23}, + {YACA_ENCRYPT_AES, YACA_BCM_CFB, 256, YACA_INVALID_PADDING, 17}, + {YACA_ENCRYPT_AES, YACA_BCM_CFB1, 256, YACA_INVALID_PADDING, 23}, + {YACA_ENCRYPT_AES, YACA_BCM_CFB8, 256, YACA_INVALID_PADDING, 29}, + {YACA_ENCRYPT_AES, YACA_BCM_CTR, 256, YACA_INVALID_PADDING, 21}, + {YACA_ENCRYPT_AES, YACA_BCM_ECB, 256, YACA_INVALID_PADDING, 9}, + {YACA_ENCRYPT_AES, YACA_BCM_ECB, 256, YACA_PADDING_NONE, 3}, + {YACA_ENCRYPT_AES, YACA_BCM_ECB, 256, YACA_PADDING_PKCS7, 15}, + {YACA_ENCRYPT_AES, YACA_BCM_OFB, 256, YACA_INVALID_PADDING, 13}, + + {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_CBC, 64, YACA_INVALID_PADDING, 31}, + {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_CBC, 64, YACA_PADDING_NONE, 22}, + {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_CBC, 64, YACA_PADDING_PKCS7, 39}, + {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_CFB, 64, YACA_INVALID_PADDING, 24}, + {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_CFB1, 64, YACA_INVALID_PADDING, 11}, + {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_CFB8, 64, YACA_INVALID_PADDING, 22}, + {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_ECB, 64, YACA_INVALID_PADDING, 7}, + {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_ECB, 64, YACA_PADDING_NONE, 19}, + {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_ECB, 64, YACA_PADDING_PKCS7, 9}, + {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_OFB, 64, YACA_INVALID_PADDING, 2}, + + {YACA_ENCRYPT_UNSAFE_3DES_2TDEA, YACA_BCM_CBC, 128, YACA_INVALID_PADDING, 16}, + {YACA_ENCRYPT_UNSAFE_3DES_2TDEA, YACA_BCM_CBC, 128, YACA_PADDING_NONE, 25}, + {YACA_ENCRYPT_UNSAFE_3DES_2TDEA, YACA_BCM_CBC, 128, YACA_PADDING_PKCS7, 26}, + {YACA_ENCRYPT_UNSAFE_3DES_2TDEA, YACA_BCM_CFB, 128, YACA_INVALID_PADDING, 23}, + {YACA_ENCRYPT_UNSAFE_3DES_2TDEA, YACA_BCM_ECB, 128, YACA_INVALID_PADDING, 13}, + {YACA_ENCRYPT_UNSAFE_3DES_2TDEA, YACA_BCM_ECB, 128, YACA_PADDING_NONE, 10}, + {YACA_ENCRYPT_UNSAFE_3DES_2TDEA, YACA_BCM_ECB, 128, YACA_PADDING_PKCS7, 29}, + {YACA_ENCRYPT_UNSAFE_3DES_2TDEA, YACA_BCM_OFB, 128, YACA_INVALID_PADDING, 32}, + + {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_CBC, 192, YACA_INVALID_PADDING, 39}, + {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_CBC, 192, YACA_PADDING_NONE, 29}, + {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_CBC, 192, YACA_PADDING_PKCS7, 19}, + {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_CFB, 192, YACA_INVALID_PADDING, 9}, + {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_CFB1, 192, YACA_INVALID_PADDING, 44}, + {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_CFB8, 192, YACA_INVALID_PADDING, 33}, + {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_ECB, 192, YACA_INVALID_PADDING, 22}, + {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_ECB, 192, YACA_PADDING_NONE, 11}, + {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_ECB, 192, YACA_PADDING_PKCS7, 13}, + {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_OFB, 192, YACA_INVALID_PADDING, 1}, + + {YACA_ENCRYPT_UNSAFE_RC4, YACA_BCM_NONE, 256, YACA_INVALID_PADDING, 17}, + + {YACA_ENCRYPT_CAST5, YACA_BCM_CBC, 128, YACA_INVALID_PADDING, 3}, + {YACA_ENCRYPT_CAST5, YACA_BCM_CBC, 128, YACA_PADDING_NONE, 24}, + {YACA_ENCRYPT_CAST5, YACA_BCM_CBC, 128, YACA_PADDING_PKCS7, 21}, + {YACA_ENCRYPT_CAST5, YACA_BCM_CFB, 128, YACA_INVALID_PADDING, 19}, + {YACA_ENCRYPT_CAST5, YACA_BCM_ECB, 128, YACA_INVALID_PADDING, 7}, + {YACA_ENCRYPT_CAST5, YACA_BCM_ECB, 128, YACA_PADDING_NONE, 6}, + {YACA_ENCRYPT_CAST5, YACA_BCM_ECB, 128, YACA_PADDING_PKCS7, 18}, + {YACA_ENCRYPT_CAST5, YACA_BCM_OFB, 128, YACA_INVALID_PADDING, 2}, + }; + + for (const auto &sa: sargs) { + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key_prv = YACA_KEY_NULL, key_pub = YACA_KEY_NULL; + yaca_key_h key_sym = YACA_KEY_NULL, iv = YACA_KEY_NULL; + + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len = 0, decrypted_len = 0; + + generate_asymmetric_keys(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_1024BIT, &key_prv, &key_pub); + + /* SEAL */ + { + ret = yaca_seal_initialize(&ctx, key_pub, sa.algo, sa.bcm, + sa.key_bit_len, &key_sym, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + size_t total = allocate_output(ctx, INPUT_DATA_SIZE, sa.split, encrypted); + size_t written; + + call_update_loop(ctx, INPUT_DATA, INPUT_DATA_SIZE, + encrypted, encrypted_len, sa.split, + yaca_seal_update); + + if (sa.padding != YACA_INVALID_PADDING) { + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, &sa.padding, + sizeof(yaca_padding_e)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + ret = yaca_seal_finalize(ctx, encrypted + encrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + encrypted_len += written; + + BOOST_REQUIRE(encrypted_len <= total); + ret = yaca_realloc(encrypted_len, (void **)&encrypted); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* OPEN */ + { + ret = yaca_open_initialize(&ctx, key_prv, sa.algo, sa.bcm, + sa.key_bit_len, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + if (sa.padding != YACA_INVALID_PADDING) { + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, &sa.padding, + sizeof(yaca_padding_e)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + size_t total = allocate_output(ctx, encrypted_len, sa.split, decrypted); + size_t written; + + call_update_loop(ctx, encrypted, encrypted_len, + decrypted, decrypted_len, sa.split, + yaca_open_update); + + ret = yaca_open_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len += written; + + BOOST_REQUIRE(decrypted_len <= total); + ret = yaca_realloc(decrypted_len, (void **)&decrypted); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + BOOST_REQUIRE(decrypted_len == INPUT_DATA_SIZE); + ret = yaca_memcmp(INPUT_DATA, decrypted, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_key_destroy(key_prv); + yaca_key_destroy(key_pub); + yaca_key_destroy(key_sym); + yaca_key_destroy(iv); + yaca_free(encrypted); + yaca_free(decrypted); + } +} + +BOOST_FIXTURE_TEST_CASE(T702__negative__seal_open, InitDebugFixture) +{ + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL, ctx_encrypt = YACA_CONTEXT_NULL; + yaca_key_h key_rsa_prv = YACA_KEY_NULL, key_rsa_pub = YACA_KEY_NULL; + yaca_key_h key_rsa_prv2 = YACA_KEY_NULL, key_rsa_pub2 = YACA_KEY_NULL; + yaca_key_h key_dsa_prv = YACA_KEY_NULL, key_dsa_pub = YACA_KEY_NULL; + yaca_key_h key_sym = YACA_KEY_NULL, key_sym2 = YACA_KEY_NULL; + yaca_key_h iv = YACA_KEY_NULL, iv2 = YACA_KEY_NULL; + yaca_padding_e pad_pkcs7 = YACA_PADDING_PKCS7; + yaca_padding_e pad_invalid = YACA_PADDING_X931; + size_t len = 128; + + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len = 0, decrypted_len = 0; + + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_256BIT, &key_sym2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_generate(YACA_KEY_TYPE_IV, YACA_KEY_LENGTH_IV_128BIT, &iv2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_encrypt_initialize(&ctx_encrypt, YACA_ENCRYPT_AES, YACA_BCM_CBC, key_sym2, iv2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + generate_asymmetric_keys(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_1024BIT, &key_rsa_prv, &key_rsa_pub); + generate_asymmetric_keys(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_1024BIT, &key_rsa_prv2, &key_rsa_pub2); + generate_asymmetric_keys(YACA_KEY_TYPE_DSA_PRIV, YACA_KEY_LENGTH_1024BIT, &key_dsa_prv, &key_dsa_pub); + + /* get an encrypted key_sym2 */ + yaca_key_destroy(key_sym2); + key_sym2 = YACA_KEY_NULL; + ret = yaca_seal_initialize(&ctx, key_rsa_pub2, YACA_ENCRYPT_AES, YACA_BCM_CBC, + YACA_KEY_LENGTH_256BIT, &key_sym2, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_key_destroy(iv); + iv = YACA_KEY_NULL; + + /* SEAL */ + { + ret = yaca_seal_initialize(NULL, key_rsa_pub, YACA_ENCRYPT_AES, YACA_BCM_CBC, + YACA_KEY_LENGTH_256BIT, &key_sym, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_initialize(&ctx, YACA_KEY_NULL, YACA_ENCRYPT_AES, YACA_BCM_CBC, + YACA_KEY_LENGTH_256BIT, &key_sym, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_initialize(&ctx, key_rsa_prv, YACA_ENCRYPT_AES, YACA_BCM_CBC, + YACA_KEY_LENGTH_256BIT, &key_sym, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_initialize(&ctx, key_dsa_pub, YACA_ENCRYPT_AES, YACA_BCM_CBC, + YACA_KEY_LENGTH_256BIT, &key_sym, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_initialize(&ctx, key_dsa_prv, YACA_ENCRYPT_AES, YACA_BCM_CBC, + YACA_KEY_LENGTH_256BIT, &key_sym, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_initialize(&ctx, key_sym2, YACA_ENCRYPT_AES, YACA_BCM_CBC, + YACA_KEY_LENGTH_256BIT, &key_sym, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_initialize(&ctx, key_rsa_pub, YACA_INVALID_ENCRYPT_ALGORITHM, YACA_BCM_CBC, + YACA_KEY_LENGTH_256BIT, &key_sym, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_initialize(&ctx, key_rsa_pub, YACA_ENCRYPT_AES, YACA_INVALID_BLOCK_CIPHER_MODE, + YACA_KEY_LENGTH_256BIT, &key_sym, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_initialize(&ctx, key_rsa_pub, YACA_ENCRYPT_AES, YACA_BCM_CBC, + 257, &key_sym, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_initialize(&ctx, key_rsa_pub, YACA_ENCRYPT_AES, YACA_BCM_CBC, + YACA_KEY_LENGTH_256BIT, NULL, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_initialize(&ctx, key_rsa_pub, YACA_ENCRYPT_AES, YACA_BCM_CBC, + YACA_KEY_LENGTH_256BIT, &key_sym, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_initialize(&ctx, key_rsa_pub, YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_CTR, + YACA_KEY_LENGTH_256BIT, &key_sym, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_initialize(&ctx, key_rsa_pub, YACA_ENCRYPT_AES, YACA_BCM_CBC, + YACA_KEY_LENGTH_256BIT, &key_sym, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_get_output_length(ctx, INPUT_DATA_SIZE, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + size_t total = allocate_output(ctx, INPUT_DATA_SIZE, 1, encrypted); + size_t written; + + ret = yaca_seal_update(YACA_CONTEXT_NULL, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_update(ctx_encrypt, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_update(ctx, NULL, INPUT_DATA_SIZE, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_update(ctx, INPUT_DATA, 0, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + encrypted_len = written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_RC2_EFFECTIVE_KEY_BITS, + &len, sizeof(size_t)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad_invalid, sizeof(yaca_padding_e)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad_pkcs7, 1); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, &pad_pkcs7, + sizeof(yaca_padding_e)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_seal_finalize(YACA_CONTEXT_NULL, encrypted + encrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_finalize(ctx_encrypt, encrypted + encrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_finalize(ctx, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_finalize(ctx, encrypted + encrypted_len, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_finalize(ctx, encrypted + encrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + encrypted_len += written; + BOOST_REQUIRE(encrypted_len <= total); + ret = yaca_realloc(encrypted_len, (void **)&encrypted); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, &pad_pkcs7, + sizeof(yaca_padding_e)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_finalize(ctx, encrypted + encrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* OPEN */ + { + ret = yaca_open_initialize(NULL, key_rsa_prv, YACA_ENCRYPT_AES, YACA_BCM_CBC, + YACA_KEY_LENGTH_256BIT, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_initialize(&ctx, key_rsa_pub, YACA_ENCRYPT_AES, YACA_BCM_CBC, + YACA_KEY_LENGTH_256BIT, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_initialize(&ctx, key_dsa_prv, YACA_ENCRYPT_AES, YACA_BCM_CBC, + YACA_KEY_LENGTH_256BIT, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_initialize(&ctx, key_dsa_pub, YACA_ENCRYPT_AES, YACA_BCM_CBC, + YACA_KEY_LENGTH_256BIT, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_initialize(&ctx, key_sym2, YACA_ENCRYPT_AES, YACA_BCM_CBC, + YACA_KEY_LENGTH_256BIT, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_initialize(&ctx, key_rsa_prv, YACA_INVALID_ENCRYPT_ALGORITHM, YACA_BCM_CBC, + YACA_KEY_LENGTH_256BIT, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_initialize(&ctx, key_rsa_prv, YACA_ENCRYPT_AES, YACA_INVALID_BLOCK_CIPHER_MODE, + YACA_KEY_LENGTH_256BIT, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_initialize(&ctx, key_rsa_prv, YACA_ENCRYPT_AES, YACA_BCM_CBC, + YACA_KEY_LENGTH_192BIT, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_initialize(&ctx, key_rsa_prv, YACA_ENCRYPT_AES, YACA_BCM_CBC, + YACA_KEY_LENGTH_256BIT, YACA_KEY_NULL, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_initialize(&ctx, key_rsa_prv, YACA_ENCRYPT_AES, YACA_BCM_CBC, + YACA_KEY_LENGTH_256BIT, key_sym2, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_initialize(&ctx, key_rsa_prv, YACA_ENCRYPT_AES, YACA_BCM_CBC, + YACA_KEY_LENGTH_256BIT, key_rsa_prv, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_initialize(&ctx, key_rsa_prv, YACA_ENCRYPT_AES, YACA_BCM_CBC, + YACA_KEY_LENGTH_256BIT, iv, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_initialize(&ctx, key_rsa_prv, YACA_ENCRYPT_AES, YACA_BCM_CBC, + YACA_KEY_LENGTH_256BIT, key_sym, YACA_KEY_NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_initialize(&ctx, key_rsa_prv, YACA_ENCRYPT_AES, YACA_BCM_CBC, + YACA_KEY_LENGTH_256BIT, key_sym, key_sym2); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_initialize(&ctx, key_rsa_prv, YACA_ENCRYPT_AES, YACA_BCM_CBC, + YACA_KEY_LENGTH_256BIT, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_RC2_EFFECTIVE_KEY_BITS, + &len, sizeof(size_t)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad_invalid, 1); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad_pkcs7, sizeof(yaca_padding_e)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_get_output_length(ctx, encrypted_len, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_open_update(YACA_CONTEXT_NULL, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_update(ctx_encrypt, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_update(ctx, NULL, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_update(ctx, encrypted, 0, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_update(ctx, encrypted, encrypted_len, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len = written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad_pkcs7, sizeof(yaca_padding_e)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_finalize(YACA_CONTEXT_NULL, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_finalize(ctx_encrypt, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_finalize(ctx, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_finalize(ctx, decrypted + decrypted_len, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + /* OPEN, wrong asym key */ + { + ret = yaca_open_initialize(&ctx, key_rsa_prv2, YACA_ENCRYPT_AES, YACA_BCM_CBC, + YACA_KEY_LENGTH_256BIT, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + } + + /* OPEN, wrong BCM */ + { + ret = yaca_open_initialize(&ctx, key_rsa_prv, YACA_ENCRYPT_AES, YACA_BCM_ECB, + YACA_KEY_LENGTH_256BIT, key_sym, YACA_KEY_NULL); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad_pkcs7, sizeof(yaca_padding_e)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len = written; + + ret = yaca_open_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + /* OPEN, wrong symmetric key */ + { + ret = yaca_open_initialize(&ctx, key_rsa_prv, YACA_ENCRYPT_AES, YACA_BCM_CBC, + YACA_KEY_LENGTH_256BIT, key_sym2, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + } + + /* OPEN, broken the end of ciphertext */ + { + encrypted[encrypted_len - 1] = ~encrypted[encrypted_len - 1]; + encrypted[encrypted_len - 2] = ~encrypted[encrypted_len - 2]; + + ret = yaca_open_initialize(&ctx, key_rsa_prv, YACA_ENCRYPT_AES, YACA_BCM_CBC, + YACA_KEY_LENGTH_256BIT, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad_pkcs7, sizeof(yaca_padding_e)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len = written; + + ret = yaca_open_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + yaca_key_destroy(key_rsa_prv); + yaca_key_destroy(key_rsa_pub); + yaca_key_destroy(key_rsa_prv2); + yaca_key_destroy(key_rsa_pub2); + yaca_key_destroy(key_dsa_prv); + yaca_key_destroy(key_dsa_pub); + yaca_key_destroy(key_sym); + yaca_key_destroy(key_sym2); + yaca_key_destroy(iv); + yaca_free(encrypted); +} + +BOOST_FIXTURE_TEST_CASE(T703__positive__seal_open_rc2, InitDebugFixture) +{ + struct seal_args { + yaca_block_cipher_mode_e bcm; + size_t key_bit_len; + size_t effective_key_bits; + size_t split; + }; + + const std::vector sargs = { + {YACA_BCM_CBC, 128, IGNORE, 11}, + {YACA_BCM_CBC, 192, 64, 22}, + {YACA_BCM_CBC, 200, 128, 3}, + {YACA_BCM_CBC, 192, 255, 7}, + {YACA_BCM_CBC, 192, 713, 2}, + {YACA_BCM_CBC, 224, 1, 19}, + {YACA_BCM_CBC, 256, 1024, 19}, + {YACA_BCM_CFB, 192, IGNORE, 13}, + {YACA_BCM_CFB, 192, 333, 33}, + {YACA_BCM_ECB, 272, IGNORE, 8}, + {YACA_BCM_ECB, 192, 666, 15}, + {YACA_BCM_OFB, 520, IGNORE, 25}, + {YACA_BCM_OFB, 224, 999, 35}, + }; + + for (const auto &sa: sargs) { + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key_prv = YACA_KEY_NULL, key_pub = YACA_KEY_NULL; + yaca_key_h key_sym = YACA_KEY_NULL, iv = YACA_KEY_NULL; + + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len = 0, decrypted_len = 0; + + generate_asymmetric_keys(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_1024BIT, &key_prv, &key_pub); + + /* SEAL */ + { + ret = yaca_seal_initialize(&ctx, key_pub, YACA_ENCRYPT_UNSAFE_RC2, sa.bcm, + sa.key_bit_len, &key_sym, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + if (sa.effective_key_bits != IGNORE) { + ret = yaca_context_set_property(ctx, YACA_PROPERTY_RC2_EFFECTIVE_KEY_BITS, + &sa.effective_key_bits, sizeof(size_t)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + size_t total = allocate_output(ctx, INPUT_DATA_SIZE, sa.split, encrypted); + size_t written; + + call_update_loop(ctx, INPUT_DATA, INPUT_DATA_SIZE, + encrypted, encrypted_len, sa.split, + yaca_seal_update); + + ret = yaca_seal_finalize(ctx, encrypted + encrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + encrypted_len += written; + + BOOST_REQUIRE(encrypted_len <= total); + ret = yaca_realloc(encrypted_len, (void **)&encrypted); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* OPEN */ + { + ret = yaca_open_initialize(&ctx, key_prv, YACA_ENCRYPT_UNSAFE_RC2, sa.bcm, + sa.key_bit_len, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + if (sa.effective_key_bits != IGNORE) { + ret = yaca_context_set_property(ctx, YACA_PROPERTY_RC2_EFFECTIVE_KEY_BITS, + &sa.effective_key_bits, sizeof(size_t)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + size_t total = allocate_output(ctx, encrypted_len, sa.split, decrypted); + size_t written; + + call_update_loop(ctx, encrypted, encrypted_len, + decrypted, decrypted_len, sa.split, + yaca_open_update); + + ret = yaca_open_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len += written; + + BOOST_REQUIRE(decrypted_len <= total); + ret = yaca_realloc(decrypted_len, (void **)&decrypted); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + BOOST_REQUIRE(decrypted_len == INPUT_DATA_SIZE); + ret = yaca_memcmp(INPUT_DATA, decrypted, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_key_destroy(key_prv); + yaca_key_destroy(key_pub); + yaca_key_destroy(key_sym); + yaca_key_destroy(iv); + yaca_free(encrypted); + yaca_free(decrypted); + } +} + +BOOST_FIXTURE_TEST_CASE(T704__negative__encrypt_decrypt_rc2, InitDebugFixture) +{ + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key_prv = YACA_KEY_NULL, key_pub = YACA_KEY_NULL; + yaca_key_h key_sym = YACA_KEY_NULL, iv = YACA_KEY_NULL; + + generate_asymmetric_keys(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_1024BIT, &key_prv, &key_pub); + + /* SEAL */ + { + ret = yaca_seal_initialize(&ctx, key_pub, YACA_ENCRYPT_UNSAFE_RC2, YACA_BCM_CFB1, + YACA_KEY_LENGTH_192BIT, &key_sym, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_initialize(&ctx, key_pub, YACA_ENCRYPT_UNSAFE_RC2, YACA_BCM_CTR, + YACA_KEY_LENGTH_192BIT, &key_sym, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_initialize(&ctx, key_pub, YACA_ENCRYPT_UNSAFE_RC2, YACA_BCM_CBC, + YACA_KEY_LENGTH_192BIT, &key_sym, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* OPEN */ + { + ret = yaca_open_initialize(&ctx, key_prv, YACA_ENCRYPT_UNSAFE_RC2, YACA_BCM_CFB1, + YACA_KEY_LENGTH_192BIT, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_initialize(&ctx, key_prv, YACA_ENCRYPT_UNSAFE_RC2, YACA_BCM_CTR, + YACA_KEY_LENGTH_192BIT, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + } + + yaca_key_destroy(key_prv); + yaca_key_destroy(key_pub); + yaca_key_destroy(key_sym); + yaca_key_destroy(iv); +} + +BOOST_FIXTURE_TEST_CASE(T705__positive__open_seal_ccm, InitDebugFixture) +{ + struct seal_args { + size_t key_bit_len; + size_t ccm_tag_len; + size_t aad_len; + }; + + const std::vector sargs = { + {128, IGNORE, IGNORE}, + {128, 4, IGNORE}, + {128, IGNORE, 13}, + {128, 6, 23}, + + {192, IGNORE, IGNORE}, + {192, 10, IGNORE}, + {192, IGNORE, 21}, + {192, 8, 17}, + + {256, IGNORE, IGNORE}, + {256, 16, IGNORE}, + {256, IGNORE, 55}, + {256, 12, 33}, + }; + + for (const auto &sa: sargs) { + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key_prv = YACA_KEY_NULL, key_pub = YACA_KEY_NULL; + yaca_key_h key_sym = YACA_KEY_NULL, iv = YACA_KEY_NULL; + + char *tag = NULL, *aad = NULL; + size_t tag_len; + + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len, decrypted_len; + + generate_asymmetric_keys(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_1024BIT, &key_prv, &key_pub); + + /* SEAL */ + { + ret = yaca_seal_initialize(&ctx, key_pub, YACA_ENCRYPT_AES, YACA_BCM_CCM, + sa.key_bit_len, &key_sym, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + size_t total = allocate_output(ctx, INPUT_DATA_SIZE, 1, encrypted); + size_t written; + + if (sa.ccm_tag_len != IGNORE) { + tag_len = sa.ccm_tag_len; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG_LEN, + &tag_len, sizeof(tag_len)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + if (sa.aad_len != IGNORE) { + ret = yaca_malloc(sa.aad_len, (void**)&aad); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_randomize_bytes(aad, sa.aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_seal_update(ctx, NULL, INPUT_DATA_SIZE, + NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, + aad, sa.aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + ret = yaca_seal_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + encrypted_len = written; + + ret = yaca_seal_finalize(ctx, encrypted + encrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + encrypted_len += written; + + BOOST_REQUIRE(encrypted_len <= total); + ret = yaca_realloc(encrypted_len, (void **)&encrypted); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_get_property(ctx, YACA_PROPERTY_CCM_TAG, (void**)&tag, &tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* OPEN */ + { + ret = yaca_open_initialize(&ctx, key_prv, YACA_ENCRYPT_AES, YACA_BCM_CCM, + sa.key_bit_len, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + size_t total = allocate_output(ctx, encrypted_len, 1, decrypted); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG, tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + size_t written; + + if (sa.aad_len != IGNORE) { + ret = yaca_open_update(ctx, NULL, encrypted_len, + NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, + aad, sa.aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len = written; + + ret = yaca_open_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len += written; + + BOOST_REQUIRE(decrypted_len <= total); + ret = yaca_realloc(decrypted_len, (void **)&decrypted); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + BOOST_REQUIRE(decrypted_len == INPUT_DATA_SIZE); + ret = yaca_memcmp(INPUT_DATA, decrypted, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_key_destroy(key_prv); + yaca_key_destroy(key_pub); + yaca_key_destroy(key_sym); + yaca_key_destroy(iv); + yaca_free(encrypted); + yaca_free(decrypted); + yaca_free(tag); + yaca_free(aad); + } +} + +BOOST_FIXTURE_TEST_CASE(T706__negative__open_seal_ccm, InitDebugFixture) +{ + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key_prv = YACA_KEY_NULL, key_pub = YACA_KEY_NULL; + yaca_key_h key_sym = YACA_KEY_NULL, iv = YACA_KEY_NULL; + + char *tag = NULL, *aad = NULL; + size_t tag_len = 0, tag_len_invalid = 17, aad_len = 55; + + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len, decrypted_len; + + generate_asymmetric_keys(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_1024BIT, &key_prv, &key_pub); + + ret = yaca_malloc(aad_len, (void**)&aad); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_randomize_bytes(aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + /* SEAL, AAD without pre-update */ + { + ret = yaca_seal_initialize(&ctx, key_pub, YACA_ENCRYPT_AES, YACA_BCM_CCM, + YACA_KEY_LENGTH_256BIT, &key_sym, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_key_destroy(key_sym); + key_sym = YACA_KEY_NULL; + yaca_key_destroy(iv); + iv = YACA_KEY_NULL; + } + + /* SEAL, pre-update without AAD */ + { + ret = yaca_seal_initialize(&ctx, key_pub, YACA_ENCRYPT_AES, YACA_BCM_CCM, + YACA_KEY_LENGTH_256BIT, &key_sym, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, INPUT_DATA_SIZE, 1, encrypted); + size_t written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG_LEN, + &tag_len_invalid, sizeof(tag_len_invalid)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_update(ctx, NULL, INPUT_DATA_SIZE, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_seal_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_key_destroy(key_sym); + key_sym = YACA_KEY_NULL; + yaca_key_destroy(iv); + iv = YACA_KEY_NULL; + } + + /* SEAL */ + { + ret = yaca_seal_initialize(&ctx, key_pub, YACA_ENCRYPT_AES, YACA_BCM_CCM, + YACA_KEY_LENGTH_256BIT, &key_sym, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + size_t total = allocate_output(ctx, INPUT_DATA_SIZE, 1, encrypted); + size_t written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG_LEN, + &tag_len_invalid, sizeof(tag_len_invalid)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_update(ctx, NULL, INPUT_DATA_SIZE, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_get_property(ctx, YACA_PROPERTY_CCM_TAG, (void**)&tag, &tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_update(ctx, NULL, INPUT_DATA_SIZE, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_seal_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_seal_update(ctx, NULL, INPUT_DATA_SIZE, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + encrypted_len = written; + + ret = yaca_seal_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_finalize(ctx, encrypted + encrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + encrypted_len += written; + BOOST_REQUIRE(encrypted_len <= total); + ret = yaca_realloc(encrypted_len, (void **)&encrypted); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_finalize(ctx, encrypted + encrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_get_property(ctx, YACA_PROPERTY_CCM_TAG, (void**)&tag, &tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* OPEN, no TAG */ + { + ret = yaca_open_initialize(&ctx, key_prv, YACA_ENCRYPT_AES, YACA_BCM_CCM, + YACA_KEY_LENGTH_256BIT, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_open_update(ctx, NULL, encrypted_len, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + /* OPEN, AAD without pre-update */ + { + ret = yaca_open_initialize(&ctx, key_prv, YACA_ENCRYPT_AES, YACA_BCM_CCM, + YACA_KEY_LENGTH_256BIT, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG, tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* OPEN, pre-update without AAD */ + { + ret = yaca_open_initialize(&ctx, key_prv, YACA_ENCRYPT_AES, YACA_BCM_CCM, + YACA_KEY_LENGTH_256BIT, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG, tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_open_update(ctx, NULL, encrypted_len, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + /* OPEN, no AAD */ + { + ret = yaca_open_initialize(&ctx, key_prv, YACA_ENCRYPT_AES, YACA_BCM_CCM, + YACA_KEY_LENGTH_256BIT, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG, tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + /* OPEN */ + { + ret = yaca_open_initialize(&ctx, key_prv, YACA_ENCRYPT_AES, YACA_BCM_CCM, + YACA_KEY_LENGTH_256BIT, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG, tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_open_update(ctx, NULL, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_update(ctx, encrypted, encrypted_len, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_update(ctx, NULL, encrypted_len, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_open_update(ctx, NULL, encrypted_len, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len = written; + + ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG, tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + /* OPEN, broken TAG */ + { + char *tag2 = NULL; + ret = yaca_malloc(tag_len, (void**)&tag2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + memcpy((void*)tag2, (void*)tag, tag_len); + tag2[0] = ~tag2[0]; + tag2[1] = ~tag2[1]; + + ret = yaca_open_initialize(&ctx, key_prv, YACA_ENCRYPT_AES, YACA_BCM_CCM, + YACA_KEY_LENGTH_256BIT, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG, tag2, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_open_update(ctx, NULL, encrypted_len, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + yaca_free(tag2); + } + + /* OPEN, broken AAD */ + { + char *aad2 = NULL; + ret = yaca_malloc(aad_len, (void**)&aad2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + memcpy((void*)aad2, (void*)aad, aad_len); + aad2[0] = ~aad2[0]; + aad2[1] = ~aad2[1]; + + ret = yaca_open_initialize(&ctx, key_prv, YACA_ENCRYPT_AES, YACA_BCM_CCM, + YACA_KEY_LENGTH_256BIT, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG, tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_open_update(ctx, NULL, encrypted_len, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, aad2, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + yaca_free(aad2); + } + + /* OPEN, broken ciphertext */ + { + encrypted[0] = ~encrypted[0]; + encrypted[1] = ~encrypted[1]; + + ret = yaca_open_initialize(&ctx, key_prv, YACA_ENCRYPT_AES, YACA_BCM_CCM, + YACA_KEY_LENGTH_256BIT, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG, tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_open_update(ctx, NULL, encrypted_len, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + yaca_key_destroy(key_prv); + yaca_key_destroy(key_pub); + yaca_key_destroy(key_sym); + yaca_key_destroy(iv); + yaca_free(encrypted); + yaca_free(tag); + yaca_free(aad); +} + +BOOST_FIXTURE_TEST_CASE(T707__positive__seal_open_gcm, InitDebugFixture) +{ + struct seal_args { + size_t key_bit_len; + size_t gcm_tag_len; + size_t aad_len; + size_t split; + }; + + const std::vector sargs = { + {128, IGNORE, IGNORE, 11}, + {128, 4, IGNORE, 12}, + {128, IGNORE, 21, 13}, + {128, 13, 22, 14}, + + {192, IGNORE, IGNORE, 22}, + {192, 8, IGNORE, 23}, + {192, IGNORE, 32, 24}, + {192, 15, 33, 25}, + + {256, IGNORE, IGNORE, 33}, + {256, 14, IGNORE, 34}, + {256, IGNORE, 17, 35}, + {256, 16, 44, 36}, + }; + + for (const auto &sa: sargs) { + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key_prv = YACA_KEY_NULL, key_pub = YACA_KEY_NULL; + yaca_key_h key_sym = YACA_KEY_NULL, iv = YACA_KEY_NULL; + + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len = 0, decrypted_len = 0; + + char *tag = NULL, *aad = NULL; + size_t tag_len; + + generate_asymmetric_keys(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_1024BIT, &key_prv, &key_pub); + + /* SEAL */ + { + ret = yaca_seal_initialize(&ctx, key_pub, YACA_ENCRYPT_AES, YACA_BCM_GCM, + sa.key_bit_len, &key_sym, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + size_t total = allocate_output(ctx, INPUT_DATA_SIZE, sa.split, encrypted); + size_t written; + + if (sa.aad_len != IGNORE) { + ret = yaca_malloc(sa.aad_len, (void**)&aad); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_randomize_bytes(aad, sa.aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_AAD, + aad, sa.aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + call_update_loop(ctx, INPUT_DATA, INPUT_DATA_SIZE, + encrypted, encrypted_len, sa.split, + yaca_seal_update); + + ret = yaca_seal_finalize(ctx, encrypted + encrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + encrypted_len += written; + + BOOST_REQUIRE(encrypted_len <= total); + ret = yaca_realloc(encrypted_len, (void **)&encrypted); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + if (sa.gcm_tag_len != IGNORE) { + tag_len = sa.gcm_tag_len; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_TAG_LEN, + &tag_len, sizeof(tag_len)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + } + + ret = yaca_context_get_property(ctx, YACA_PROPERTY_GCM_TAG, + (void**)&tag, &tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* OPEN */ + { + ret = yaca_open_initialize(&ctx, key_prv, YACA_ENCRYPT_AES, YACA_BCM_GCM, + sa.key_bit_len, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + size_t total = allocate_output(ctx, encrypted_len, sa.split, decrypted); + size_t written; + + if (sa.aad_len != IGNORE) { + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_AAD, + aad, sa.aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + call_update_loop(ctx, encrypted, encrypted_len, + decrypted, decrypted_len, sa.split, + yaca_open_update); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_TAG, + tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_open_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len += written; + + BOOST_REQUIRE(decrypted_len <= total); + ret = yaca_realloc(decrypted_len, (void **)&decrypted); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + BOOST_REQUIRE(decrypted_len == INPUT_DATA_SIZE); + ret = yaca_memcmp(INPUT_DATA, decrypted, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_key_destroy(key_prv); + yaca_key_destroy(key_pub); + yaca_key_destroy(key_sym); + yaca_key_destroy(iv); + yaca_free(encrypted); + yaca_free(decrypted); + yaca_free(tag); + yaca_free(aad); + } +} + +BOOST_FIXTURE_TEST_CASE(T708__negative__seal_open_gcm, InitDebugFixture) +{ + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key_prv = YACA_KEY_NULL, key_pub = YACA_KEY_NULL; + yaca_key_h key_sym = YACA_KEY_NULL, iv = YACA_KEY_NULL; + + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len = 0, decrypted_len = 0; + + char *tag = NULL, *aad = NULL; + size_t tag_len = 0, tag_len_invalid = 17, aad_len = 55; + + generate_asymmetric_keys(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_1024BIT, &key_prv, &key_pub); + + ret = yaca_malloc(aad_len, (void**)&aad); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_randomize_bytes(aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + /* SEAL */ + { + ret = yaca_seal_initialize(&ctx, key_pub, YACA_ENCRYPT_AES, YACA_BCM_GCM, + YACA_KEY_LENGTH_256BIT, &key_sym, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + size_t total = allocate_output(ctx, INPUT_DATA_SIZE, 1, encrypted); + size_t written; + + ret = yaca_seal_update(ctx, NULL, INPUT_DATA_SIZE, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_seal_update(ctx, NULL, INPUT_DATA_SIZE, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + encrypted_len = written; + + ret = yaca_seal_finalize(ctx, encrypted + encrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + encrypted_len += written; + BOOST_REQUIRE(encrypted_len <= total); + ret = yaca_realloc(encrypted_len, (void **)&encrypted); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_seal_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_seal_finalize(ctx, encrypted + encrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_TAG_LEN, + &tag_len_invalid, sizeof(tag_len_invalid)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_get_property(ctx, YACA_PROPERTY_GCM_TAG, + (void**)&tag, &tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* OPEN, no TAG */ + { + ret = yaca_open_initialize(&ctx, key_prv, YACA_ENCRYPT_AES, YACA_BCM_GCM, + YACA_KEY_LENGTH_256BIT, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len = written; + + ret = yaca_open_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + /* OPEN, no AAD */ + { + ret = yaca_open_initialize(&ctx, key_prv, YACA_ENCRYPT_AES, YACA_BCM_GCM, + YACA_KEY_LENGTH_256BIT, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len = written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_TAG, tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_open_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + /* OPEN */ + { + ret = yaca_open_initialize(&ctx, key_prv, YACA_ENCRYPT_AES, YACA_BCM_GCM, + YACA_KEY_LENGTH_256BIT, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_open_update(ctx, NULL, encrypted_len, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_open_update(ctx, NULL, encrypted_len, NULL, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len = written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_TAG, tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_open_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_open_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + /* OPEN, broken TAG */ + { + char *tag2 = NULL; + ret = yaca_malloc(tag_len, (void**)&tag2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + memcpy((void*)tag2, (void*)tag, tag_len); + tag2[0] = ~tag2[0]; + tag2[1] = ~tag2[1]; + + ret = yaca_open_initialize(&ctx, key_prv, YACA_ENCRYPT_AES, YACA_BCM_GCM, + YACA_KEY_LENGTH_256BIT, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len = written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_TAG, tag2, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_open_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + yaca_free(tag2); + } + + /* OPEN, broken AAD */ + { + char *aad2 = NULL; + ret = yaca_malloc(aad_len, (void**)&aad2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + memcpy((void*)aad2, (void*)aad, aad_len); + aad2[0] = ~aad2[0]; + aad2[1] = ~aad2[1]; + + ret = yaca_open_initialize(&ctx, key_prv, YACA_ENCRYPT_AES, YACA_BCM_GCM, + YACA_KEY_LENGTH_256BIT, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_AAD, aad2, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len = written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_TAG, tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_open_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + yaca_free(aad2); + } + + /* OPEN, broken ciphertext */ + { + encrypted[0] = ~encrypted[0]; + encrypted[1] = ~encrypted[1]; + + ret = yaca_open_initialize(&ctx, key_prv, YACA_ENCRYPT_AES, YACA_BCM_GCM, + YACA_KEY_LENGTH_256BIT, key_sym, iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + allocate_output(ctx, encrypted_len, 1, decrypted); + size_t written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_AAD, aad, aad_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, &written); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + decrypted_len = written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_TAG, tag, tag_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_open_finalize(ctx, decrypted + decrypted_len, &written); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(decrypted); + decrypted = NULL; + } + + yaca_key_destroy(key_prv); + yaca_key_destroy(key_pub); + yaca_key_destroy(key_sym); + yaca_key_destroy(iv); + yaca_free(encrypted); + yaca_free(tag); + yaca_free(aad); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/test_sign.cpp b/tests/test_sign.cpp new file mode 100644 index 0000000..9aed73d --- /dev/null +++ b/tests/test_sign.cpp @@ -0,0 +1,950 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Pawelczyk + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file test_sign.cpp + * @author Lukasz Pawelczyk + * @brief Signature API unit tests. + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "common.h" + + +namespace { + +using update_fun_3_t = int(yaca_context_h ctx, const char *input, size_t input_len); + +void call_update_loop(yaca_context_h &ctx, const char *input, size_t input_len, + size_t split, update_fun_3_t *fun) +{ + BOOST_REQUIRE_MESSAGE(split >= 1, "Fix your test"); + + int ret; + size_t left = input_len; + size_t part = input_len / split; + + BOOST_REQUIRE_MESSAGE(part >= 1, "Fix your test"); + + for (;;) { + ret = fun(ctx, input, part); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + input += part; + left -= part; + + if (left == 0) + break; + + if (left < part) + part = left; + } +} + +} //namespace + + +BOOST_AUTO_TEST_SUITE(TESTS_SIGN) + +BOOST_FIXTURE_TEST_CASE(T801__positive__sign_verify, InitDebugFixture) +{ + struct sign_args { + yaca_key_type_e type_prv; + yaca_key_bit_length_e key_bit_len; + yaca_digest_algorithm_e digest; + yaca_padding_e pad; + size_t split; + }; + + const std::vector sargs = { + {YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_512BIT, + YACA_DIGEST_MD5, YACA_INVALID_PADDING, 27}, + {YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_1024BIT, + YACA_DIGEST_MD5, YACA_PADDING_PKCS1_PSS, 14}, + {YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_2048BIT, + YACA_DIGEST_SHA1, YACA_PADDING_X931, 34}, + {YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_1024BIT, + YACA_DIGEST_SHA384, YACA_PADDING_PKCS1, 9}, + {YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_2048BIT, + YACA_DIGEST_SHA512, YACA_PADDING_PKCS1_PSS, 12}, + + {YACA_KEY_TYPE_DSA_PRIV, YACA_KEY_LENGTH_512BIT, + YACA_DIGEST_SHA256, YACA_INVALID_PADDING, 5}, + {YACA_KEY_TYPE_DSA_PRIV, YACA_KEY_LENGTH_1024BIT, + YACA_DIGEST_SHA224, YACA_INVALID_PADDING, 31}, + {YACA_KEY_TYPE_DSA_PRIV, YACA_KEY_LENGTH_2048BIT, + YACA_DIGEST_SHA1, YACA_INVALID_PADDING, 29}, + {YACA_KEY_TYPE_DSA_PRIV, YACA_KEY_LENGTH_1024BIT, + YACA_DIGEST_SHA384, YACA_INVALID_PADDING, 19}, + {YACA_KEY_TYPE_DSA_PRIV, YACA_KEY_LENGTH_2048BIT, + YACA_DIGEST_SHA512, YACA_INVALID_PADDING, 11}, + + {YACA_KEY_TYPE_EC_PRIV, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_EC_SECP256K1, + YACA_DIGEST_SHA256, YACA_INVALID_PADDING, 13}, + {YACA_KEY_TYPE_EC_PRIV, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_EC_SECP384R1, + YACA_DIGEST_SHA224, YACA_INVALID_PADDING, 23}, + {YACA_KEY_TYPE_EC_PRIV, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_EC_SECP521R1, + YACA_DIGEST_SHA1, YACA_INVALID_PADDING, 33}, + {YACA_KEY_TYPE_EC_PRIV, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_EC_PRIME192V1, + YACA_DIGEST_SHA384, YACA_INVALID_PADDING, 22}, + {YACA_KEY_TYPE_EC_PRIV, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_EC_PRIME256V1, + YACA_DIGEST_SHA512, YACA_INVALID_PADDING, 20}, + }; + + for (const auto &sa: sargs) { + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key_prv = YACA_KEY_NULL, key_pub = YACA_KEY_NULL; + + char *signature = NULL; + size_t signature_len; + + generate_asymmetric_keys(sa.type_prv, sa.key_bit_len, &key_prv, &key_pub); + + /* SIGN */ + { + ret = yaca_sign_initialize(&ctx, sa.digest, key_prv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + if (sa.pad != YACA_INVALID_PADDING) { + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &sa.pad, sizeof(sa.pad)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + call_update_loop(ctx, INPUT_DATA, INPUT_DATA_SIZE, + sa.split, &yaca_sign_update); + + ret = yaca_context_get_output_length(ctx, 0, &signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_malloc(signature_len, (void **)&signature); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_sign_finalize(ctx, signature, &signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* VERIFY */ + { + ret = yaca_verify_initialize(&ctx, sa.digest, key_pub); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + if (sa.pad != YACA_INVALID_PADDING) { + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &sa.pad, sizeof(sa.pad)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + call_update_loop(ctx, INPUT_DATA, INPUT_DATA_SIZE, + sa.split + 3, &yaca_verify_update); + + ret = yaca_verify_finalize(ctx, signature, signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + yaca_key_destroy(key_prv); + yaca_key_destroy(key_pub); + yaca_free(signature); + } +} + +BOOST_FIXTURE_TEST_CASE(T802__negative__sign_verify, InitDebugFixture) +{ + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL, ctx_digest = YACA_CONTEXT_NULL; + yaca_key_h key_rsa_prv = YACA_KEY_NULL, key_rsa_pub = YACA_KEY_NULL; + yaca_key_h key_rsa_prv2 = YACA_KEY_NULL, key_rsa_pub2 = YACA_KEY_NULL; + yaca_key_h key_dsa_prv = YACA_KEY_NULL, key_dsa_pub = YACA_KEY_NULL; + yaca_key_h key_sym = YACA_KEY_NULL, key_rsa_prv_short = YACA_KEY_NULL; + yaca_padding_e pad_invalid = YACA_PADDING_X931, pad_none = YACA_PADDING_NONE; + yaca_padding_e pad = YACA_PADDING_PKCS1, pad2 = YACA_PADDING_PKCS1_PSS; + + size_t len = 128; + + char *signature = NULL; + size_t signature_len; + + ret = yaca_digest_initialize(&ctx_digest, YACA_DIGEST_MD5); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_256BIT, &key_sym); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + generate_asymmetric_keys(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_512BIT, &key_rsa_prv_short); + generate_asymmetric_keys(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_1024BIT, &key_rsa_prv, &key_rsa_pub); + generate_asymmetric_keys(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_1024BIT, &key_rsa_prv2, &key_rsa_pub2); + generate_asymmetric_keys(YACA_KEY_TYPE_DSA_PRIV, YACA_KEY_LENGTH_1024BIT, &key_dsa_prv, &key_dsa_pub); + + /* SIGN */ + { + ret = yaca_sign_initialize(NULL, YACA_DIGEST_MD5, key_rsa_prv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_sign_initialize(&ctx, YACA_INVALID_DIGEST_ALGORITHM, key_rsa_prv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_sign_initialize(&ctx, YACA_DIGEST_MD5, YACA_KEY_NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_sign_initialize(&ctx, YACA_DIGEST_MD5, key_rsa_pub); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_sign_initialize(&ctx, YACA_DIGEST_MD5, key_sym); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_sign_initialize(&ctx, YACA_DIGEST_SHA384, key_rsa_prv_short); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_sign_initialize(&ctx, YACA_DIGEST_MD5, key_rsa_prv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_INVALID_PROPERTY, + &pad, sizeof(pad)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + NULL, sizeof(pad)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad, 1); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_RC2_EFFECTIVE_KEY_BITS, + &len, sizeof(size_t)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad_none, sizeof(pad_none)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad_invalid, sizeof(pad_invalid)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad, sizeof(pad)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_sign_update(YACA_CONTEXT_NULL, INPUT_DATA, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_sign_update(ctx, NULL, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_sign_update(ctx, INPUT_DATA, 0); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_sign_update(ctx_digest, INPUT_DATA, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_sign_update(ctx, INPUT_DATA, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_get_output_length(ctx, 0, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_get_output_length(ctx, 1, &signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_get_output_length(ctx, 0, &signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_malloc(signature_len, (void **)&signature); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_sign_finalize(YACA_CONTEXT_NULL, signature, &signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_sign_finalize(ctx, NULL, &signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_sign_finalize(ctx, signature, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_sign_finalize(ctx, signature, &signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_sign_update(ctx, INPUT_DATA, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_sign_finalize(ctx, signature, &signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* VERIFY */ + { + ret = yaca_verify_initialize(NULL, YACA_DIGEST_MD5, key_rsa_pub); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_verify_initialize(&ctx, YACA_INVALID_DIGEST_ALGORITHM, key_rsa_pub); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_verify_initialize(&ctx, YACA_DIGEST_MD5, YACA_KEY_NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_verify_initialize(&ctx, YACA_DIGEST_MD5, key_rsa_prv); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_verify_initialize(&ctx, YACA_DIGEST_MD5, key_sym); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_verify_initialize(&ctx, YACA_DIGEST_SHA384, key_rsa_prv_short); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_verify_initialize(&ctx, YACA_DIGEST_MD5, key_rsa_pub); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_INVALID_PROPERTY, + &pad, sizeof(pad)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + NULL, sizeof(pad)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad, 1); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_RC2_EFFECTIVE_KEY_BITS, + &len, sizeof(size_t)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad_none, sizeof(pad_none)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad_invalid, sizeof(pad_invalid)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad, sizeof(pad)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_verify_update(YACA_CONTEXT_NULL, INPUT_DATA, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_verify_update(ctx, NULL, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_verify_update(ctx, INPUT_DATA, 0); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_verify_update(ctx_digest, INPUT_DATA, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_verify_update(ctx, INPUT_DATA, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_verify_finalize(YACA_CONTEXT_NULL, signature, signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_verify_finalize(ctx, NULL, signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_verify_finalize(ctx, signature, 0); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_verify_finalize(ctx_digest, signature, signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_verify_finalize(ctx, signature, signature_len - 1); + BOOST_REQUIRE(ret == YACA_ERROR_DATA_MISMATCH); + + ret = yaca_verify_finalize(ctx, signature + 1, signature_len - 1); + BOOST_REQUIRE(ret == YACA_ERROR_DATA_MISMATCH); + + ret = yaca_verify_finalize(ctx, signature, signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_verify_update(ctx, INPUT_DATA, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_verify_finalize(ctx, signature, signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* VERIFY, wrong algo */ + { + ret = yaca_verify_initialize(&ctx, YACA_DIGEST_SHA1, key_rsa_pub); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad, sizeof(pad)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_verify_update(ctx, INPUT_DATA, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_verify_finalize(ctx, signature, signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_DATA_MISMATCH); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* VERIFY, wrong key */ + { + ret = yaca_verify_initialize(&ctx, YACA_DIGEST_MD5, key_rsa_pub2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad, sizeof(pad)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_verify_update(ctx, INPUT_DATA, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_verify_finalize(ctx, signature, signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_DATA_MISMATCH); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* VERIFY, wrong padding */ + { + ret = yaca_verify_initialize(&ctx, YACA_DIGEST_MD5, key_rsa_pub); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad2, sizeof(pad2)); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_verify_update(ctx, INPUT_DATA, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_verify_finalize(ctx, signature, signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_DATA_MISMATCH); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* SIGN DSA */ + { + ret = yaca_sign_initialize(&ctx, YACA_DIGEST_SHA1, key_dsa_prv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad, sizeof(pad)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad2, sizeof(pad2)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad_invalid, sizeof(pad_invalid)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad_none, sizeof(pad_none)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* VERIFY DSA */ + { + ret = yaca_verify_initialize(&ctx, YACA_DIGEST_SHA1, key_dsa_pub); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad, sizeof(pad)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad2, sizeof(pad2)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad_invalid, sizeof(pad_invalid)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &pad_none, sizeof(pad_none)); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + yaca_key_destroy(key_rsa_prv); + yaca_key_destroy(key_rsa_pub); + yaca_key_destroy(key_rsa_prv2); + yaca_key_destroy(key_rsa_pub2); + yaca_key_destroy(key_rsa_prv_short); + yaca_key_destroy(key_dsa_prv); + yaca_key_destroy(key_dsa_pub); + yaca_key_destroy(key_sym); + yaca_context_destroy(ctx_digest); + yaca_free(signature); +} + +BOOST_FIXTURE_TEST_CASE(T803__positive__sign_cmac, InitDebugFixture) +{ + struct cmac_args { + yaca_key_type_e type; + yaca_key_bit_length_e len; + yaca_encrypt_algorithm_e algo; + size_t split; + }; + + const std::vector cargs = { + {YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_256BIT, + YACA_ENCRYPT_AES, 11}, + {YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_UNSAFE_128BIT, + YACA_ENCRYPT_CAST5, 22}, + {YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_192BIT, + YACA_ENCRYPT_3DES_3TDEA, 33}, + {YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_256BIT, + YACA_ENCRYPT_UNSAFE_RC2, 44}, + {YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_UNSAFE_64BIT, + YACA_ENCRYPT_UNSAFE_DES, 13}, + + {YACA_KEY_TYPE_DES, YACA_KEY_LENGTH_UNSAFE_128BIT, + YACA_ENCRYPT_AES, 15}, + {YACA_KEY_TYPE_DES, YACA_KEY_LENGTH_UNSAFE_128BIT, + YACA_ENCRYPT_CAST5, 41}, + {YACA_KEY_TYPE_DES, YACA_KEY_LENGTH_192BIT, + YACA_ENCRYPT_3DES_3TDEA, 17}, + {YACA_KEY_TYPE_DES, YACA_KEY_LENGTH_UNSAFE_128BIT, + YACA_ENCRYPT_UNSAFE_RC2, 9}, + {YACA_KEY_TYPE_DES, YACA_KEY_LENGTH_UNSAFE_64BIT, + YACA_ENCRYPT_UNSAFE_DES, 12}, + }; + + for (const auto &ca: cargs) { + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key = YACA_KEY_NULL; + + char *signature = NULL, *signature2 = NULL; + size_t signature_len, signature2_len; + + ret = yaca_key_generate(ca.type, ca.len, &key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + /* SIGN */ + { + ret = yaca_sign_initialize_cmac(&ctx, ca.algo, key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + call_update_loop(ctx, INPUT_DATA, INPUT_DATA_SIZE, + ca.split, yaca_sign_update); + + ret = yaca_context_get_output_length(ctx, 0, &signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_malloc(signature_len, (void **)&signature); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_sign_finalize(ctx, signature, &signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* VERIFY */ + { + ret = yaca_sign_initialize_cmac(&ctx, ca.algo, key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + call_update_loop(ctx, INPUT_DATA, INPUT_DATA_SIZE, + ca.split + 3, yaca_sign_update); + + ret = yaca_context_get_output_length(ctx, 0, &signature2_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_malloc(signature2_len, (void **)&signature2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_sign_finalize(ctx, signature2, &signature2_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + + BOOST_REQUIRE(signature_len == signature2_len); + ret = yaca_memcmp(signature, signature2, signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + yaca_key_destroy(key); + yaca_free(signature); + yaca_free(signature2); + } +} + +BOOST_FIXTURE_TEST_CASE(T804__negative__sign_cmac, InitDebugFixture) +{ + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key = YACA_KEY_NULL, key2 = YACA_KEY_NULL; + yaca_key_h key_rsa = YACA_KEY_NULL, key_dsa = YACA_KEY_NULL; + + char *signature = NULL, *signature2 = NULL; + size_t signature_len, signature2_len; + + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_192BIT, &key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_192BIT, &key2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + generate_asymmetric_keys(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_512BIT, &key_rsa); + generate_asymmetric_keys(YACA_KEY_TYPE_DSA_PRIV, YACA_KEY_LENGTH_512BIT, &key_dsa); + + /* SIGN */ + { + ret = yaca_sign_initialize_cmac(NULL, YACA_ENCRYPT_AES, key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_sign_initialize_cmac(&ctx, YACA_INVALID_ENCRYPT_ALGORITHM, key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_sign_initialize_cmac(&ctx, YACA_ENCRYPT_AES, YACA_KEY_NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_sign_initialize_cmac(&ctx, YACA_ENCRYPT_AES, key_rsa); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_sign_initialize_cmac(&ctx, YACA_ENCRYPT_AES, key_dsa); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_sign_initialize_cmac(&ctx, YACA_ENCRYPT_AES, key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_sign_update(ctx, INPUT_DATA, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_get_output_length(ctx, 0, &signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_malloc(signature_len, (void **)&signature); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_sign_finalize(ctx, signature, &signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* VERIFY, wrong algo */ + { + ret = yaca_sign_initialize_cmac(&ctx, YACA_ENCRYPT_3DES_3TDEA, key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_sign_update(ctx, INPUT_DATA, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_get_output_length(ctx, 0, &signature2_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_malloc(signature2_len, (void **)&signature2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_sign_finalize(ctx, signature2, &signature2_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + signature2_len = std::min(signature_len, signature2_len); + ret = yaca_memcmp(signature, signature2, signature2_len); + BOOST_REQUIRE(ret == YACA_ERROR_DATA_MISMATCH); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(signature2); + signature2 = NULL; + } + + /* VERIFY, wrong key */ + { + ret = yaca_sign_initialize_cmac(&ctx, YACA_ENCRYPT_AES, key2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_sign_update(ctx, INPUT_DATA, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_get_output_length(ctx, 0, &signature2_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_malloc(signature2_len, (void **)&signature2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_sign_finalize(ctx, signature2, &signature2_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + BOOST_REQUIRE(signature_len == signature2_len); + ret = yaca_memcmp(signature, signature2, signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_DATA_MISMATCH); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(signature2); + signature2 = NULL; + } + + yaca_key_destroy(key); + yaca_key_destroy(key2); + yaca_key_destroy(key_rsa); + yaca_key_destroy(key_dsa); + yaca_free(signature); +} + +BOOST_FIXTURE_TEST_CASE(T805__positive__sign_hmac, InitDebugFixture) +{ + struct hmac_args { + yaca_key_type_e type; + yaca_key_bit_length_e len; + yaca_digest_algorithm_e digest; + size_t split; + }; + + const std::vector hargs = { + {YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_256BIT, + YACA_DIGEST_MD5, 13}, + {YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_UNSAFE_128BIT, + YACA_DIGEST_SHA1, 32}, + {YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_192BIT, + YACA_DIGEST_SHA224, 23}, + {YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_256BIT, + YACA_DIGEST_SHA256, 20}, + {YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_UNSAFE_64BIT, + YACA_DIGEST_SHA384, 13}, + + {YACA_KEY_TYPE_DES, YACA_KEY_LENGTH_UNSAFE_128BIT, + YACA_DIGEST_MD5, 9}, + {YACA_KEY_TYPE_DES, YACA_KEY_LENGTH_UNSAFE_128BIT, + YACA_DIGEST_SHA1, 7}, + {YACA_KEY_TYPE_DES, YACA_KEY_LENGTH_192BIT, + YACA_DIGEST_SHA224, 14}, + {YACA_KEY_TYPE_DES, YACA_KEY_LENGTH_UNSAFE_128BIT, + YACA_DIGEST_SHA384, 20}, + {YACA_KEY_TYPE_DES, YACA_KEY_LENGTH_UNSAFE_64BIT, + YACA_DIGEST_SHA512, 10}, + }; + + for (const auto &ha: hargs) { + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key = YACA_KEY_NULL; + + char *signature = NULL, *signature2 = NULL; + size_t signature_len, signature2_len; + + ret = yaca_key_generate(ha.type, ha.len, &key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + /* SIGN */ + { + ret = yaca_sign_initialize_hmac(&ctx, ha.digest, key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + call_update_loop(ctx, INPUT_DATA, INPUT_DATA_SIZE, + ha.split, yaca_sign_update); + + ret = yaca_context_get_output_length(ctx, 0, &signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_malloc(signature_len, (void **)&signature); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_sign_finalize(ctx, signature, &signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* VERIFY */ + { + ret = yaca_sign_initialize_hmac(&ctx, ha.digest, key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + call_update_loop(ctx, INPUT_DATA, INPUT_DATA_SIZE, + ha.split + 3, yaca_sign_update); + + ret = yaca_context_get_output_length(ctx, 0, &signature2_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_malloc(signature2_len, (void **)&signature2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_sign_finalize(ctx, signature2, &signature2_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + + BOOST_REQUIRE(signature_len == signature2_len); + ret = yaca_memcmp(signature, signature2, signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + yaca_key_destroy(key); + yaca_free(signature); + yaca_free(signature2); + } +} + +BOOST_FIXTURE_TEST_CASE(T806__negative__sign_hmac, InitDebugFixture) +{ + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key = YACA_KEY_NULL, key2 = YACA_KEY_NULL; + yaca_key_h key_rsa = YACA_KEY_NULL, key_dsa = YACA_KEY_NULL; + + char *signature = NULL, *signature2 = NULL; + size_t signature_len, signature2_len; + + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_192BIT, &key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_192BIT, &key2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + generate_asymmetric_keys(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_512BIT, &key_rsa); + generate_asymmetric_keys(YACA_KEY_TYPE_DSA_PRIV, YACA_KEY_LENGTH_512BIT, &key_dsa); + + /* SIGN */ + { + ret = yaca_sign_initialize_hmac(NULL, YACA_DIGEST_MD5, key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_sign_initialize_hmac(&ctx, YACA_INVALID_DIGEST_ALGORITHM, key); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_sign_initialize_hmac(&ctx, YACA_DIGEST_MD5, YACA_KEY_NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_sign_initialize_hmac(&ctx, YACA_DIGEST_MD5, key_rsa); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_sign_initialize_hmac(&ctx, YACA_DIGEST_MD5, key_dsa); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_sign_initialize_hmac(&ctx, YACA_DIGEST_MD5, key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_sign_update(ctx, INPUT_DATA, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_get_output_length(ctx, 0, &signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_malloc(signature_len, (void **)&signature); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_sign_finalize(ctx, signature, &signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* VERIFY, wrong algo */ + { + ret = yaca_sign_initialize_hmac(&ctx, YACA_DIGEST_SHA1, key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_sign_update(ctx, INPUT_DATA, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_get_output_length(ctx, 0, &signature2_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_malloc(signature2_len, (void **)&signature2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_sign_finalize(ctx, signature2, &signature2_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + signature2_len = std::min(signature_len, signature2_len); + ret = yaca_memcmp(signature, signature2, signature2_len); + BOOST_REQUIRE(ret == YACA_ERROR_DATA_MISMATCH); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(signature2); + signature2 = NULL; + } + + /* VERIFY, wrong key */ + { + ret = yaca_sign_initialize_hmac(&ctx, YACA_DIGEST_MD5, key2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_sign_update(ctx, INPUT_DATA, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_context_get_output_length(ctx, 0, &signature2_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_malloc(signature2_len, (void **)&signature2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_sign_finalize(ctx, signature2, &signature2_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + BOOST_REQUIRE(signature_len == signature2_len); + ret = yaca_memcmp(signature, signature2, signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_DATA_MISMATCH); + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + yaca_free(signature2); + signature2 = NULL; + } + + yaca_key_destroy(key); + yaca_key_destroy(key2); + yaca_key_destroy(key_rsa); + yaca_key_destroy(key_dsa); + yaca_free(signature); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/test_simple.cpp b/tests/test_simple.cpp new file mode 100644 index 0000000..59f25eb --- /dev/null +++ b/tests/test_simple.cpp @@ -0,0 +1,755 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Pawelczyk + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file test_simple.cpp + * @author Lukasz Pawelczyk + * @brief Simple API unit tests. + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "common.h" + + +BOOST_AUTO_TEST_SUITE(TESTS_SIMPLE) + +BOOST_FIXTURE_TEST_CASE(T301__positive__simple_encrypt_decrypt, InitDebugFixture) +{ + struct encrypt_args { + yaca_encrypt_algorithm_e algo; + yaca_block_cipher_mode_e bcm; + size_t key_bit_len; + }; + + const std::vector eargs = { + {yaca_encrypt_algorithm_e::YACA_ENCRYPT_AES, + yaca_block_cipher_mode_e::YACA_BCM_CBC, + yaca_key_bit_length_e::YACA_KEY_LENGTH_256BIT}, + {yaca_encrypt_algorithm_e::YACA_ENCRYPT_AES, + yaca_block_cipher_mode_e::YACA_BCM_CFB, + yaca_key_bit_length_e::YACA_KEY_LENGTH_256BIT}, + {yaca_encrypt_algorithm_e::YACA_ENCRYPT_AES, + yaca_block_cipher_mode_e::YACA_BCM_ECB, + yaca_key_bit_length_e::YACA_KEY_LENGTH_IV_128BIT}, + {yaca_encrypt_algorithm_e::YACA_ENCRYPT_UNSAFE_DES, + yaca_block_cipher_mode_e::YACA_BCM_CBC, + yaca_key_bit_length_e::YACA_KEY_LENGTH_UNSAFE_64BIT}, + {yaca_encrypt_algorithm_e::YACA_ENCRYPT_3DES_3TDEA, + yaca_block_cipher_mode_e::YACA_BCM_ECB, + yaca_key_bit_length_e::YACA_KEY_LENGTH_192BIT}, + {yaca_encrypt_algorithm_e::YACA_ENCRYPT_UNSAFE_RC4, + yaca_block_cipher_mode_e::YACA_BCM_NONE, + yaca_key_bit_length_e::YACA_KEY_LENGTH_192BIT}, + {yaca_encrypt_algorithm_e::YACA_ENCRYPT_CAST5, + yaca_block_cipher_mode_e::YACA_BCM_OFB, + yaca_key_bit_length_e::YACA_KEY_LENGTH_UNSAFE_128BIT} + }; + + for (const auto &ea: eargs) { + int ret; + yaca_key_h sym = YACA_KEY_NULL, iv = YACA_KEY_NULL; + size_t iv_bit_len; + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len, decrypted_len; + + ret = yaca_encrypt_get_iv_bit_length(ea.algo, ea.bcm, ea.key_bit_len, &iv_bit_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, ea.key_bit_len, &sym); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + if (iv_bit_len > 0) { + ret = yaca_key_generate(YACA_KEY_TYPE_IV, iv_bit_len, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + } + + ret = yaca_simple_encrypt(ea.algo, ea.bcm, sym, iv, INPUT_DATA, INPUT_DATA_SIZE, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_simple_decrypt(ea.algo, ea.bcm, sym, iv, encrypted, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + BOOST_REQUIRE(decrypted_len == INPUT_DATA_SIZE); + ret = yaca_memcmp(INPUT_DATA, decrypted, INPUT_DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_key_destroy(sym); + yaca_key_destroy(iv); + yaca_free(encrypted); + yaca_free(decrypted); + } +} + +BOOST_FIXTURE_TEST_CASE(T302__negative__simple_encrypt_decrypt, InitDebugFixture) +{ + int ret; + yaca_key_h sym = YACA_KEY_NULL, iv = YACA_KEY_NULL; + yaca_key_h sym2 = YACA_KEY_NULL, iv2 = YACA_KEY_NULL; + size_t iv_bit_len; + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len, decrypted_len; + + ret = yaca_encrypt_get_iv_bit_length(YACA_ENCRYPT_AES, YACA_BCM_CBC, + YACA_KEY_LENGTH_256BIT, &iv_bit_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_256BIT, &sym); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_192BIT, &sym2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_generate(YACA_KEY_TYPE_IV, iv_bit_len, &iv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_generate(YACA_KEY_TYPE_IV, iv_bit_len * 2, &iv2); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_simple_encrypt(YACA_INVALID_ENCRYPT_ALGORITHM, YACA_BCM_CBC, sym, iv, + INPUT_DATA, INPUT_DATA_SIZE, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_encrypt(YACA_ENCRYPT_AES, YACA_INVALID_BLOCK_CIPHER_MODE, sym, iv, + INPUT_DATA, INPUT_DATA_SIZE, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_encrypt(YACA_ENCRYPT_AES, YACA_BCM_CBC, YACA_KEY_NULL, iv, + INPUT_DATA, INPUT_DATA_SIZE, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_encrypt(YACA_ENCRYPT_AES, YACA_BCM_CBC, sym, YACA_KEY_NULL, + INPUT_DATA, INPUT_DATA_SIZE, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_encrypt(YACA_ENCRYPT_AES, YACA_BCM_CBC, sym, iv, + NULL, INPUT_DATA_SIZE, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_encrypt(YACA_ENCRYPT_AES, YACA_BCM_CBC, sym, iv, + INPUT_DATA, 0, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_encrypt(YACA_ENCRYPT_AES, YACA_BCM_CBC, sym, iv, + INPUT_DATA, INPUT_DATA_SIZE, + NULL, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_encrypt(YACA_ENCRYPT_AES, YACA_BCM_CBC, sym, iv, + INPUT_DATA, INPUT_DATA_SIZE, + &encrypted, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_encrypt(YACA_ENCRYPT_AES, YACA_BCM_CBC, sym, iv, + INPUT_DATA, INPUT_DATA_SIZE, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_simple_decrypt(YACA_INVALID_ENCRYPT_ALGORITHM, YACA_BCM_CBC, sym, iv, + encrypted, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_decrypt(YACA_ENCRYPT_AES, YACA_INVALID_BLOCK_CIPHER_MODE, sym, iv, + encrypted, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_decrypt(YACA_ENCRYPT_AES, YACA_BCM_CBC, NULL, iv, + encrypted, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_decrypt(YACA_ENCRYPT_AES, YACA_BCM_CBC, sym, NULL, + encrypted, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_decrypt(YACA_ENCRYPT_AES, YACA_BCM_CBC, sym, iv, + NULL, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_decrypt(YACA_ENCRYPT_AES, YACA_BCM_CBC, sym, iv, + encrypted, 0, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_decrypt(YACA_ENCRYPT_AES, YACA_BCM_CBC, sym, iv, + encrypted, encrypted_len, + NULL, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_decrypt(YACA_ENCRYPT_AES, YACA_BCM_CBC, sym, iv, + encrypted, encrypted_len, + &decrypted, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_decrypt(YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_CBC, sym, iv, + encrypted, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_decrypt(YACA_ENCRYPT_AES, YACA_BCM_ECB, sym, iv, + encrypted, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_decrypt(YACA_ENCRYPT_AES, YACA_BCM_CBC, sym2, iv, + encrypted, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_decrypt(YACA_ENCRYPT_AES, YACA_BCM_CBC, sym, iv2, + encrypted, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_decrypt(YACA_ENCRYPT_AES, YACA_BCM_CBC, sym, iv, + encrypted, encrypted_len - 1, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_decrypt(YACA_ENCRYPT_AES, YACA_BCM_CBC, sym, iv, + encrypted + 1, encrypted_len - 1, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + encrypted[encrypted_len - 1] = ~encrypted[encrypted_len - 1]; + encrypted[encrypted_len - 2] = ~encrypted[encrypted_len - 2]; + ret = yaca_simple_decrypt(YACA_ENCRYPT_AES, YACA_BCM_CBC, sym, iv, + encrypted, encrypted_len, + &decrypted, &decrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_key_destroy(sym); + yaca_key_destroy(sym2); + yaca_key_destroy(iv); + yaca_key_destroy(iv2); + yaca_free(encrypted); + yaca_free(decrypted); +} + +BOOST_FIXTURE_TEST_CASE(T303__positive__simple_calculate_digest, InitDebugFixture) +{ + struct digest_args { + yaca_digest_algorithm_e algo = YACA_DIGEST_SHA256; + size_t expected; + }; + + const std::vector dargs = { + {yaca_digest_algorithm_e::YACA_DIGEST_MD5, 16}, + {yaca_digest_algorithm_e::YACA_DIGEST_SHA1, 20}, + {yaca_digest_algorithm_e::YACA_DIGEST_SHA224, 28}, + {yaca_digest_algorithm_e::YACA_DIGEST_SHA256, 32}, + {yaca_digest_algorithm_e::YACA_DIGEST_SHA384, 48}, + {yaca_digest_algorithm_e::YACA_DIGEST_SHA512, 64} + }; + + for (const auto &da: dargs) { + int ret; + char *digest = NULL; + size_t digest_len; + + ret = yaca_simple_calculate_digest(da.algo, INPUT_DATA, INPUT_DATA_SIZE, + &digest, &digest_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + BOOST_REQUIRE(digest_len == da.expected); + + yaca_free(digest); + } +} + +BOOST_FIXTURE_TEST_CASE(T304__negative__simple_calculate_digest, InitDebugFixture) +{ + int ret; + char *digest = NULL; + size_t digest_len; + + ret = yaca_simple_calculate_digest(YACA_INVALID_DIGEST_ALGORITHM, INPUT_DATA, INPUT_DATA_SIZE, + &digest, &digest_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_calculate_digest(YACA_DIGEST_SHA256, NULL, INPUT_DATA_SIZE, + &digest, &digest_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_calculate_digest(YACA_DIGEST_SHA256, INPUT_DATA, 0, + &digest, &digest_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_calculate_digest(YACA_DIGEST_SHA256, INPUT_DATA, INPUT_DATA_SIZE, + NULL, &digest_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_calculate_digest(YACA_DIGEST_SHA256, INPUT_DATA, INPUT_DATA_SIZE, + &digest, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); +} + +BOOST_FIXTURE_TEST_CASE(T305__positive__simple_calculate_verify_signature, InitDebugFixture) +{ + struct signature_args { + yaca_key_type_e type; + yaca_key_bit_length_e len; + yaca_digest_algorithm_e algo; + }; + + const std::vector sargs = { + {yaca_key_type_e::YACA_KEY_TYPE_RSA_PRIV, + yaca_key_bit_length_e::YACA_KEY_LENGTH_1024BIT, + yaca_digest_algorithm_e::YACA_DIGEST_MD5}, + {yaca_key_type_e::YACA_KEY_TYPE_RSA_PRIV, + yaca_key_bit_length_e::YACA_KEY_LENGTH_2048BIT, + yaca_digest_algorithm_e::YACA_DIGEST_MD5}, + {yaca_key_type_e::YACA_KEY_TYPE_RSA_PRIV, + yaca_key_bit_length_e::YACA_KEY_LENGTH_1024BIT, + yaca_digest_algorithm_e::YACA_DIGEST_SHA256}, + {yaca_key_type_e::YACA_KEY_TYPE_DSA_PRIV, + yaca_key_bit_length_e::YACA_KEY_LENGTH_1024BIT, + yaca_digest_algorithm_e::YACA_DIGEST_SHA256}, + {yaca_key_type_e::YACA_KEY_TYPE_DSA_PRIV, + yaca_key_bit_length_e::YACA_KEY_LENGTH_1024BIT, + yaca_digest_algorithm_e::YACA_DIGEST_SHA512}, + {yaca_key_type_e::YACA_KEY_TYPE_EC_PRIV, + (yaca_key_bit_length_e)yaca_key_bit_length_ec_e::YACA_KEY_LENGTH_EC_SECP256K1, + yaca_digest_algorithm_e::YACA_DIGEST_SHA256} + }; + + for (const auto &sa: sargs) { + int ret; + yaca_key_h key_priv = YACA_KEY_NULL; + yaca_key_h key_pub = YACA_KEY_NULL; + + char *signature = NULL; + size_t signature_len; + + ret = yaca_key_generate(sa.type, sa.len, &key_priv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_key_extract_public(key_priv, &key_pub); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_simple_calculate_signature(sa.algo, key_priv, + INPUT_DATA, INPUT_DATA_SIZE, + &signature, &signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + BOOST_REQUIRE(signature_len > 0); + + ret = yaca_simple_verify_signature(sa.algo, key_pub, + INPUT_DATA, INPUT_DATA_SIZE, + signature, signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_key_destroy(key_priv); + yaca_key_destroy(key_pub); + yaca_free(signature); + } +} + +BOOST_FIXTURE_TEST_CASE(T306__negative__simple_calculate_verify_signature, InitDebugFixture) +{ + int ret; + yaca_key_h key_priv = YACA_KEY_NULL, key_pub = YACA_KEY_NULL; + yaca_key_h key_ec = YACA_KEY_NULL, key_dsa = YACA_KEY_NULL; + + char *signature = NULL; + size_t signature_len; + + ret = yaca_key_generate(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_512BIT, &key_priv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_extract_public(key_priv, &key_pub); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_generate(YACA_KEY_TYPE_DSA_PRIV, YACA_KEY_LENGTH_512BIT, &key_dsa); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_generate(YACA_KEY_TYPE_EC_PRIV, YACA_KEY_LENGTH_EC_PRIME256V1, &key_ec); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_simple_calculate_signature(YACA_INVALID_DIGEST_ALGORITHM, key_priv, + INPUT_DATA, INPUT_DATA_SIZE, + &signature, &signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_calculate_signature(YACA_DIGEST_SHA384, key_priv, + INPUT_DATA, INPUT_DATA_SIZE, + &signature, &signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_calculate_signature(YACA_DIGEST_SHA512, key_priv, + INPUT_DATA, INPUT_DATA_SIZE, + &signature, &signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_calculate_signature(YACA_DIGEST_MD5, YACA_KEY_NULL, + INPUT_DATA, INPUT_DATA_SIZE, + &signature, &signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_calculate_signature(YACA_DIGEST_MD5, key_priv, + NULL, INPUT_DATA_SIZE, + &signature, &signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_calculate_signature(YACA_DIGEST_MD5, key_priv, + INPUT_DATA, 0, + &signature, &signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_calculate_signature(YACA_DIGEST_MD5, key_priv, + INPUT_DATA, INPUT_DATA_SIZE, + NULL, &signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_calculate_signature(YACA_DIGEST_MD5, key_priv, + INPUT_DATA, INPUT_DATA_SIZE, + &signature, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_calculate_signature(YACA_DIGEST_MD5, key_dsa, + INPUT_DATA, INPUT_DATA_SIZE, + &signature, &signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_calculate_signature(YACA_DIGEST_MD5, key_ec, + INPUT_DATA, INPUT_DATA_SIZE, + &signature, &signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_calculate_signature(YACA_DIGEST_MD5, key_pub, + INPUT_DATA, INPUT_DATA_SIZE, + &signature, &signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_calculate_signature(YACA_DIGEST_MD5, key_priv, + INPUT_DATA, INPUT_DATA_SIZE, + &signature, &signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_simple_verify_signature(YACA_INVALID_DIGEST_ALGORITHM, key_pub, + INPUT_DATA, INPUT_DATA_SIZE, + signature, signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_verify_signature(YACA_DIGEST_SHA384, key_pub, + INPUT_DATA, INPUT_DATA_SIZE, + signature, signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_verify_signature(YACA_DIGEST_SHA512, key_pub, + INPUT_DATA, INPUT_DATA_SIZE, + signature, signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_verify_signature(YACA_DIGEST_MD5, YACA_KEY_NULL, + INPUT_DATA, INPUT_DATA_SIZE, + signature, signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_verify_signature(YACA_DIGEST_MD5, key_priv, + INPUT_DATA, INPUT_DATA_SIZE, + signature, signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_verify_signature(YACA_DIGEST_MD5, key_ec, + INPUT_DATA, INPUT_DATA_SIZE, + signature, signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_verify_signature(YACA_DIGEST_MD5, key_pub, + NULL, INPUT_DATA_SIZE, + signature, signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_verify_signature(YACA_DIGEST_MD5, key_pub, + INPUT_DATA, 0, + signature, signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_verify_signature(YACA_DIGEST_MD5, key_pub, + INPUT_DATA, INPUT_DATA_SIZE, + NULL, signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_verify_signature(YACA_DIGEST_MD5, key_pub, + INPUT_DATA, INPUT_DATA_SIZE, + signature, 0); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_verify_signature(YACA_DIGEST_SHA1, key_pub, + INPUT_DATA, INPUT_DATA_SIZE, + signature, signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_DATA_MISMATCH); + + ret = yaca_simple_verify_signature(YACA_DIGEST_MD5, key_pub, + INPUT_DATA, INPUT_DATA_SIZE - 1, + signature, signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_DATA_MISMATCH); + + ret = yaca_simple_verify_signature(YACA_DIGEST_MD5, key_pub, + INPUT_DATA + 1, INPUT_DATA_SIZE - 1, + signature, signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_DATA_MISMATCH); + + ret = yaca_simple_verify_signature(YACA_DIGEST_MD5, key_pub, + INPUT_DATA, INPUT_DATA_SIZE, + signature, signature_len - 1); + BOOST_REQUIRE(ret == YACA_ERROR_DATA_MISMATCH); + + ret = yaca_simple_verify_signature(YACA_DIGEST_MD5, key_pub, + INPUT_DATA, INPUT_DATA_SIZE, + signature + 1, signature_len - 1); + BOOST_REQUIRE(ret == YACA_ERROR_DATA_MISMATCH); + + signature[0] = ~signature[0]; + signature[1] = ~signature[1]; + ret = yaca_simple_verify_signature(YACA_DIGEST_MD5, key_pub, + INPUT_DATA, INPUT_DATA_SIZE, + signature, signature_len); + BOOST_REQUIRE(ret == YACA_ERROR_DATA_MISMATCH); + + yaca_key_destroy(key_priv); + yaca_key_destroy(key_pub); + yaca_key_destroy(key_dsa); + yaca_key_destroy(key_ec); + yaca_free(signature); +} + +BOOST_FIXTURE_TEST_CASE(T307__positive__simple_calculate_hmac, InitDebugFixture) +{ + struct hmac_args { + yaca_key_type_e type; + yaca_key_bit_length_e len; + yaca_digest_algorithm_e algo; + }; + + const std::vector hargs = { + {yaca_key_type_e::YACA_KEY_TYPE_SYMMETRIC, + yaca_key_bit_length_e::YACA_KEY_LENGTH_256BIT, + yaca_digest_algorithm_e::YACA_DIGEST_MD5}, + {yaca_key_type_e::YACA_KEY_TYPE_SYMMETRIC, + yaca_key_bit_length_e::YACA_KEY_LENGTH_256BIT, + yaca_digest_algorithm_e::YACA_DIGEST_SHA256}, + {yaca_key_type_e::YACA_KEY_TYPE_SYMMETRIC, + yaca_key_bit_length_e::YACA_KEY_LENGTH_256BIT, + yaca_digest_algorithm_e::YACA_DIGEST_SHA512}, + {yaca_key_type_e::YACA_KEY_TYPE_DES, + yaca_key_bit_length_e::YACA_KEY_LENGTH_UNSAFE_128BIT, + yaca_digest_algorithm_e::YACA_DIGEST_SHA1}, + {yaca_key_type_e::YACA_KEY_TYPE_DES, + yaca_key_bit_length_e::YACA_KEY_LENGTH_192BIT, + yaca_digest_algorithm_e::YACA_DIGEST_SHA384} + }; + + for (const auto &ha: hargs) { + int ret; + yaca_key_h key = YACA_KEY_NULL; + char *mac1 = NULL, *mac2 = NULL; + size_t mac1_len, mac2_len; + + ret = yaca_key_generate(ha.type, ha.len, &key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_simple_calculate_hmac(ha.algo, key, + INPUT_DATA, INPUT_DATA_SIZE, + &mac1, &mac1_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_simple_calculate_hmac(ha.algo, key, + INPUT_DATA, INPUT_DATA_SIZE, + &mac2, &mac2_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + BOOST_REQUIRE(mac1_len == mac2_len); + ret = yaca_memcmp(mac1, mac2, mac1_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_key_destroy(key); + yaca_free(mac1); + yaca_free(mac2); + } +} + +BOOST_FIXTURE_TEST_CASE(T308__negative__simple_calculate_hmac, InitDebugFixture) +{ + int ret; + yaca_key_h key = YACA_KEY_NULL, key_prv = YACA_KEY_NULL; + char *mac = NULL; + size_t mac_len; + + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_256BIT, &key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_generate(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_512BIT, &key_prv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_simple_calculate_hmac(YACA_INVALID_DIGEST_ALGORITHM, key, + INPUT_DATA, INPUT_DATA_SIZE, + &mac, &mac_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_calculate_hmac(YACA_DIGEST_MD5, YACA_KEY_NULL, + INPUT_DATA, INPUT_DATA_SIZE, + &mac, &mac_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_calculate_hmac(YACA_DIGEST_MD5, key_prv, + INPUT_DATA, INPUT_DATA_SIZE, + &mac, &mac_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_calculate_hmac(YACA_DIGEST_MD5, key, + NULL, INPUT_DATA_SIZE, + &mac, &mac_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_calculate_hmac(YACA_DIGEST_MD5, key, + INPUT_DATA, 0, + &mac, &mac_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_calculate_hmac(YACA_DIGEST_MD5, key, + INPUT_DATA, INPUT_DATA_SIZE, + NULL, &mac_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_calculate_hmac(YACA_DIGEST_MD5, key, + INPUT_DATA, INPUT_DATA_SIZE, + &mac, NULL); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_key_destroy(key); + yaca_key_destroy(key_prv); +} + +BOOST_FIXTURE_TEST_CASE(T309__positive__simple_calculate_cmac, InitDebugFixture) +{ + struct cmac_args { + yaca_key_type_e type; + yaca_key_bit_length_e len; + yaca_encrypt_algorithm_e algo; + }; + + const std::vector cargs = { + {yaca_key_type_e::YACA_KEY_TYPE_SYMMETRIC, + yaca_key_bit_length_e::YACA_KEY_LENGTH_256BIT, + yaca_encrypt_algorithm_e::YACA_ENCRYPT_AES}, + {yaca_key_type_e::YACA_KEY_TYPE_SYMMETRIC, + yaca_key_bit_length_e::YACA_KEY_LENGTH_256BIT, + yaca_encrypt_algorithm_e::YACA_ENCRYPT_AES}, + {yaca_key_type_e::YACA_KEY_TYPE_SYMMETRIC, + yaca_key_bit_length_e::YACA_KEY_LENGTH_192BIT, + yaca_encrypt_algorithm_e::YACA_ENCRYPT_3DES_3TDEA}, + {yaca_key_type_e::YACA_KEY_TYPE_DES, + yaca_key_bit_length_e::YACA_KEY_LENGTH_UNSAFE_64BIT, + yaca_encrypt_algorithm_e::YACA_ENCRYPT_UNSAFE_DES}, + {yaca_key_type_e::YACA_KEY_TYPE_SYMMETRIC, + yaca_key_bit_length_e::YACA_KEY_LENGTH_UNSAFE_128BIT, + yaca_encrypt_algorithm_e::YACA_ENCRYPT_CAST5}}; + + for (const auto &ha: cargs) { + int ret; + yaca_key_h key = YACA_KEY_NULL; + char *mac1 = NULL, *mac2 = NULL; + size_t mac1_len, mac2_len; + + ret = yaca_key_generate(ha.type, ha.len, &key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_simple_calculate_cmac(ha.algo, key, + INPUT_DATA, INPUT_DATA_SIZE, + &mac1, &mac1_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_simple_calculate_cmac(ha.algo, key, + INPUT_DATA, INPUT_DATA_SIZE, + &mac2, &mac2_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + BOOST_REQUIRE(mac1_len == mac2_len); + ret = yaca_memcmp(mac1, mac2, mac1_len); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + yaca_key_destroy(key); + yaca_free(mac1); + yaca_free(mac2); + } +} + +BOOST_FIXTURE_TEST_CASE(T3010__negative__simple_calculate_cmac, InitDebugFixture) +{ + int ret; + yaca_key_h key = YACA_KEY_NULL, key_prv = YACA_KEY_NULL; + char *mac = NULL; + size_t mac_len; + + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_256BIT, &key); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + ret = yaca_key_generate(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_512BIT, &key_prv); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + ret = yaca_simple_calculate_cmac(YACA_INVALID_ENCRYPT_ALGORITHM, key, + INPUT_DATA, INPUT_DATA_SIZE, + &mac, &mac_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_calculate_cmac(YACA_ENCRYPT_AES, YACA_KEY_NULL, + INPUT_DATA, INPUT_DATA_SIZE, + &mac, &mac_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_calculate_cmac(YACA_ENCRYPT_AES, key_prv, + INPUT_DATA, INPUT_DATA_SIZE, + &mac, &mac_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_calculate_cmac(YACA_ENCRYPT_AES, key, + NULL, INPUT_DATA_SIZE, + &mac, &mac_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_calculate_cmac(YACA_ENCRYPT_AES, key, + INPUT_DATA, 0, + &mac, &mac_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_calculate_cmac(YACA_ENCRYPT_AES, key, + INPUT_DATA, INPUT_DATA_SIZE, + NULL, &mac_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_simple_calculate_cmac(YACA_ENCRYPT_AES, key, + INPUT_DATA, INPUT_DATA_SIZE, + &mac, 0); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + yaca_key_destroy(key); + yaca_key_destroy(key_prv); +} + +BOOST_AUTO_TEST_SUITE_END() -- 2.7.4 From 6913160bb8ad64572057dbc7ec96a72a0111b1f5 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Mon, 4 May 2020 17:23:09 +0200 Subject: [PATCH 12/16] OpenSSL and libc mockup infrastructure implementation Most of the OpenSSL functions used in YACA now have their mockups that the tests can control. In every YACA src file 3 lines has been added (conditional include of a redefine header). In the tests one can fail a specific or nth OpenSSL function by setting special global variables. Functions excluded from mockup are functions returning void and few specific functions use in initialization. Change-Id: I815f5fecd3a3fc7427e9f5b2d443fdba18d3d2ee --- src/crypto.c | 5 + src/digest.c | 5 + src/encrypt.c | 5 + src/key.c | 5 + src/rsa.c | 5 + src/seal.c | 5 + src/sign.c | 5 + tests/CMakeLists.txt | 3 +- tests/openssl_mock_functions.h | 207 +++++++ tests/openssl_mock_impl.c | 1198 ++++++++++++++++++++++++++++++++++++++++ tests/openssl_mock_impl.h | 203 +++++++ tests/openssl_mock_redefine.h | 235 ++++++++ 12 files changed, 1880 insertions(+), 1 deletion(-) create mode 100644 tests/openssl_mock_functions.h create mode 100644 tests/openssl_mock_impl.c create mode 100644 tests/openssl_mock_impl.h create mode 100644 tests/openssl_mock_redefine.h diff --git a/src/crypto.c b/src/crypto.c index b798196..ab94112 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -44,6 +44,11 @@ #include "internal.h" +#ifdef OPENSSL_MOCKUP_TESTS +#include "../tests/openssl_mock_redefine.h" +#endif + + static __thread bool current_thread_initialized = false; static size_t threads_cnt = 0; static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER; diff --git a/src/digest.c b/src/digest.c index 9b88442..07f7de8 100644 --- a/src/digest.c +++ b/src/digest.c @@ -31,6 +31,11 @@ #include "internal.h" +#ifdef OPENSSL_MOCKUP_TESTS +#include "../tests/openssl_mock_redefine.h" +#endif + + static const struct { yaca_digest_algorithm_e algo; const EVP_MD *(*digest)(void); diff --git a/src/encrypt.c b/src/encrypt.c index 49a4a4d..f0ef959 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -36,6 +36,11 @@ #include "internal.h" +#ifdef OPENSSL_MOCKUP_TESTS +#include "../tests/openssl_mock_redefine.h" +#endif + + static int set_encrypt_property(yaca_context_h ctx, yaca_property_e property, const void *value, size_t value_len); diff --git a/src/key.c b/src/key.c index 68def62..d94e533 100644 --- a/src/key.c +++ b/src/key.c @@ -41,6 +41,11 @@ #include "internal.h" +#ifdef OPENSSL_MOCKUP_TESTS +#include "../tests/openssl_mock_redefine.h" +#endif + + struct openssl_password_data { bool password_requested; const char *password; diff --git a/src/rsa.c b/src/rsa.c index 21077b9..cbd951b 100644 --- a/src/rsa.c +++ b/src/rsa.c @@ -34,6 +34,11 @@ #include "internal.h" +#ifdef OPENSSL_MOCKUP_TESTS +#include "../tests/openssl_mock_redefine.h" +#endif + + int rsa_padding2openssl(yaca_padding_e padding) { switch (padding) { diff --git a/src/seal.c b/src/seal.c index 27a1c21..73e7abb 100644 --- a/src/seal.c +++ b/src/seal.c @@ -34,6 +34,11 @@ #include "internal.h" +#ifdef OPENSSL_MOCKUP_TESTS +#include "../tests/openssl_mock_redefine.h" +#endif + + static int seal_generate_sym_key(yaca_encrypt_algorithm_e algo, size_t sym_key_bit_len, yaca_key_h *sym_key) diff --git a/src/sign.c b/src/sign.c index e276af6..3b4f6f6 100644 --- a/src/sign.c +++ b/src/sign.c @@ -35,6 +35,11 @@ #include "internal.h" +#ifdef OPENSSL_MOCKUP_TESTS +#include "../tests/openssl_mock_redefine.h" +#endif + + /* Operation type saved in context to recognize what * type of operation is performed and how to perform it. */ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 4ebee1a..ad3eb0d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -33,10 +33,11 @@ SET(TESTS_SOURCES test_encrypt.cpp test_seal.cpp test_sign.cpp + openssl_mock_impl.c ) FIND_PACKAGE(Boost REQUIRED unit_test_framework) -ADD_DEFINITIONS("-DBOOST_TEST_DYN_LINK") +ADD_DEFINITIONS("-DBOOST_TEST_DYN_LINK -DOPENSSL_MOCKUP_TESTS") INCLUDE_DIRECTORIES(${API_FOLDER} ${SRC_FOLDER}) INCLUDE_DIRECTORIES(SYSTEM ${YACA_DEPS_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) diff --git a/tests/openssl_mock_functions.h b/tests/openssl_mock_functions.h new file mode 100644 index 0000000..d11b692 --- /dev/null +++ b/tests/openssl_mock_functions.h @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Pawelczyk + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file openssl_mock_functions.h + * @brief + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Mockup declarations */ +int MOCK_open(const char *pathname, int flags); +ssize_t MOCK_read(int fd, void *buf, size_t count); +int MOCK_BIO_flush(BIO *b); +long MOCK_BIO_get_mem_data(BIO *b, char **pp); +BIO *MOCK_BIO_new(const BIO_METHOD *type); +BIO *MOCK_BIO_new_mem_buf(const void *buf, int len); +int MOCK_BIO_read(BIO *b, void *data, int dlen); +int MOCK_BIO_reset(BIO *b); +int MOCK_BIO_write(BIO *b, const void *data, int dlen); +CMAC_CTX *MOCK_CMAC_CTX_new(void); +int MOCK_CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, const EVP_CIPHER *cipher, ENGINE *impl); +int MOCK_DES_random_key(DES_cblock *ret); +int MOCK_DH_KDF_X9_42(unsigned char *out, size_t outlen, const unsigned char *Z, size_t Zlen, ASN1_OBJECT *key_oid, const unsigned char *ukm, size_t ukmlen, const EVP_MD *md); +int MOCK_ECDH_KDF_X9_62(unsigned char *out, size_t outlen, const unsigned char *Z, size_t Zlen, const unsigned char *sinfo, size_t sinfolen, const EVP_MD *md); +int MOCK_EC_GROUP_get_asn1_flag(const EC_GROUP *group); +int MOCK_EC_GROUP_get_curve_name(const EC_GROUP *group); +EC_KEY *MOCK_EC_KEY_new(void); +int MOCK_EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group); +int MOCK_EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx); +int MOCK_EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c); +int MOCK_EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); +EVP_CIPHER_CTX *MOCK_EVP_CIPHER_CTX_new(void); +int MOCK_EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen); +int MOCK_EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad); +int MOCK_EVP_CIPHER_iv_length(const EVP_CIPHER *cipher); +int MOCK_EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); +int MOCK_EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, ENGINE *impl, const unsigned char *key, const unsigned char *iv, int enc); +int MOCK_EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl); +int MOCK_EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s); +int MOCK_EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type); +int MOCK_EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen); +int MOCK_EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); +int MOCK_EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt); +int MOCK_EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt); +int MOCK_EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, size_t siglen); +int MOCK_EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); +int MOCK_EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt); +EVP_MD_CTX *MOCK_EVP_MD_CTX_create(void); +EVP_PKEY_CTX *MOCK_EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx); +int MOCK_EVP_MD_CTX_size(const EVP_MD_CTX *ctx); +int MOCK_EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, int p1, void *p2); +EVP_PKEY *MOCK_EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx); +EVP_PKEY_CTX *MOCK_EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e); +EVP_PKEY_CTX *MOCK_EVP_PKEY_CTX_new_id(int id, ENGINE *e); +int MOCK_EVP_PKEY_CTX_set_dh_paramgen_generator(EVP_PKEY_CTX *ctx, int gen); +int MOCK_EVP_PKEY_CTX_set_dh_paramgen_prime_len(EVP_PKEY_CTX *ctx, int len); +int MOCK_EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX *ctx, int nbits); +int MOCK_EVP_PKEY_CTX_set_ec_param_enc(EVP_PKEY_CTX *ctx, int param_enc); +int MOCK_EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid); +int MOCK_EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int mbits); +int MOCK_EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad); +int MOCK_EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key); +int MOCK_EVP_PKEY_assign_DH(EVP_PKEY *pkey, DH *key); +int MOCK_EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key); +int MOCK_EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key); +int MOCK_EVP_PKEY_bits(const EVP_PKEY *pkey); +int MOCK_EVP_PKEY_decrypt_old(unsigned char *dec_key, const unsigned char *enc_key, int enc_key_len, EVP_PKEY *private_key); +int MOCK_EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); +int MOCK_EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx); +int MOCK_EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer); +int MOCK_EVP_PKEY_encrypt_old(unsigned char *enc_key, const unsigned char *key, int key_len, EVP_PKEY *pub_key); +int MOCK_EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); +int MOCK_EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx); +EVP_PKEY *MOCK_EVP_PKEY_new(void); +EVP_PKEY *MOCK_EVP_PKEY_new_mac_key(int type, ENGINE *e, const unsigned char *key, int keylen); +int MOCK_EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); +int MOCK_EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx); +int MOCK_EVP_PKEY_size(EVP_PKEY *pkey); +int MOCK_EVP_PKEY_up_ref(EVP_PKEY *pkey); +const EVP_CIPHER *MOCK_EVP_aes_128_cbc(void); +const EVP_CIPHER *MOCK_EVP_aes_128_ccm(void); +const EVP_CIPHER *MOCK_EVP_aes_128_cfb(void); +const EVP_CIPHER *MOCK_EVP_aes_128_cfb1(void); +const EVP_CIPHER *MOCK_EVP_aes_128_cfb8(void); +const EVP_CIPHER *MOCK_EVP_aes_128_ctr(void); +const EVP_CIPHER *MOCK_EVP_aes_128_ecb(void); +const EVP_CIPHER *MOCK_EVP_aes_128_gcm(void); +const EVP_CIPHER *MOCK_EVP_aes_128_ofb(void); +const EVP_CIPHER *MOCK_EVP_aes_128_wrap(void); +const EVP_CIPHER *MOCK_EVP_aes_192_cbc(void); +const EVP_CIPHER *MOCK_EVP_aes_192_ccm(void); +const EVP_CIPHER *MOCK_EVP_aes_192_cfb(void); +const EVP_CIPHER *MOCK_EVP_aes_192_cfb1(void); +const EVP_CIPHER *MOCK_EVP_aes_192_cfb8(void); +const EVP_CIPHER *MOCK_EVP_aes_192_ctr(void); +const EVP_CIPHER *MOCK_EVP_aes_192_ecb(void); +const EVP_CIPHER *MOCK_EVP_aes_192_gcm(void); +const EVP_CIPHER *MOCK_EVP_aes_192_ofb(void); +const EVP_CIPHER *MOCK_EVP_aes_192_wrap(void); +const EVP_CIPHER *MOCK_EVP_aes_256_cbc(void); +const EVP_CIPHER *MOCK_EVP_aes_256_ccm(void); +const EVP_CIPHER *MOCK_EVP_aes_256_cfb(void); +const EVP_CIPHER *MOCK_EVP_aes_256_cfb1(void); +const EVP_CIPHER *MOCK_EVP_aes_256_cfb8(void); +const EVP_CIPHER *MOCK_EVP_aes_256_ctr(void); +const EVP_CIPHER *MOCK_EVP_aes_256_ecb(void); +const EVP_CIPHER *MOCK_EVP_aes_256_gcm(void); +const EVP_CIPHER *MOCK_EVP_aes_256_ofb(void); +const EVP_CIPHER *MOCK_EVP_aes_256_wrap(void); +const EVP_CIPHER *MOCK_EVP_cast5_cbc(void); +const EVP_CIPHER *MOCK_EVP_cast5_cfb(void); +const EVP_CIPHER *MOCK_EVP_cast5_ecb(void); +const EVP_CIPHER *MOCK_EVP_cast5_ofb(void); +const EVP_CIPHER *MOCK_EVP_des_cbc(void); +const EVP_CIPHER *MOCK_EVP_des_cfb(void); +const EVP_CIPHER *MOCK_EVP_des_cfb1(void); +const EVP_CIPHER *MOCK_EVP_des_cfb8(void); +const EVP_CIPHER *MOCK_EVP_des_ecb(void); +const EVP_CIPHER *MOCK_EVP_des_ede3_cbc(void); +const EVP_CIPHER *MOCK_EVP_des_ede3_cfb(void); +const EVP_CIPHER *MOCK_EVP_des_ede3_cfb1(void); +const EVP_CIPHER *MOCK_EVP_des_ede3_cfb8(void); +const EVP_CIPHER *MOCK_EVP_des_ede3_ecb(void); +const EVP_CIPHER *MOCK_EVP_des_ede3_ofb(void); +const EVP_CIPHER *MOCK_EVP_des_ede3_wrap(void); +const EVP_CIPHER *MOCK_EVP_des_ede_cbc(void); +const EVP_CIPHER *MOCK_EVP_des_ede_cfb(void); +const EVP_CIPHER *MOCK_EVP_des_ede_ecb(void); +const EVP_CIPHER *MOCK_EVP_des_ede_ofb(void); +const EVP_CIPHER *MOCK_EVP_des_ofb(void); +const EVP_MD *MOCK_EVP_md5(void); +const EVP_CIPHER *MOCK_EVP_rc2_cbc(void); +const EVP_CIPHER *MOCK_EVP_rc2_cfb(void); +const EVP_CIPHER *MOCK_EVP_rc2_ecb(void); +const EVP_CIPHER *MOCK_EVP_rc2_ofb(void); +const EVP_CIPHER *MOCK_EVP_rc4(void); +const EVP_MD *MOCK_EVP_sha1(void); +const EVP_MD *MOCK_EVP_sha224(void); +const EVP_MD *MOCK_EVP_sha256(void); +const EVP_MD *MOCK_EVP_sha384(void); +const EVP_MD *MOCK_EVP_sha512(void); +void *MOCK_OPENSSL_malloc(size_t num); +void *MOCK_OPENSSL_realloc(void *addr, size_t num); +EVP_PKEY *MOCK_PEM_read_bio_PUBKEY(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u); +EVP_PKEY *MOCK_PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x); +EVP_PKEY *MOCK_PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u); +X509 *MOCK_PEM_read_bio_X509(BIO *bp, X509 **x, pem_password_cb *cb, void *u); +int MOCK_PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cb, void *u); +int MOCK_PEM_write_bio_PUBKEY(BIO *bp, EVP_PKEY *x); +int MOCK_PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x); +int MOCK_PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, void *u); +int MOCK_PKCS5_PBKDF2_HMAC(const char *pass, int passlen, const unsigned char *salt, int saltlen, int iter, const EVP_MD *digest, int keylen, unsigned char *out); +int MOCK_RAND_bytes(unsigned char *buf, int num); +int MOCK_RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); +int MOCK_RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); +int MOCK_RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); +int MOCK_RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); +EVP_PKEY *MOCK_X509_get_pubkey(X509 *x); +DH *MOCK_d2i_DHparams_bio(BIO *bp, DH **x); +DSA *MOCK_d2i_DSAparams_bio(BIO *bp, DSA **x); +EC_GROUP *MOCK_d2i_ECPKParameters_bio(BIO *bp, EC_GROUP **x); +EVP_PKEY *MOCK_d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u); +EVP_PKEY *MOCK_d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a); +EVP_PKEY *MOCK_d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a); +X509 *MOCK_d2i_X509_bio(BIO *bp, X509 **x509); +int MOCK_i2d_DHparams_bio(BIO *bp, const DH *x); +int MOCK_i2d_DSAparams_bio(BIO *bp, const DSA *x); +int MOCK_i2d_ECPKParameters_bio(BIO *bp, const EC_GROUP *x); +int MOCK_i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cb, void *u); +int MOCK_i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey); +int MOCK_i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey); + +#ifdef __cplusplus +} +#endif diff --git a/tests/openssl_mock_impl.c b/tests/openssl_mock_impl.c new file mode 100644 index 0000000..7c10355 --- /dev/null +++ b/tests/openssl_mock_impl.c @@ -0,0 +1,1198 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Pawelczyk + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file openssl_mock_impl.c + * @brief + */ + +#include +#include +#include +#include + +#include + +#include "openssl_mock_impl.h" + + +unsigned MOCK_fail_nth = 0; + +static int BIO_reset_just_called = 0; +static void reset_conditions() +{ + BIO_reset_just_called = 0; +} + +#define HANDLE_FUNCTION(FNAME, VALUE, COND) \ + do { \ + if (GET_BOOL_NAME(FNAME)) { \ + GET_BOOL_NAME(FNAME) = 0; \ + return VALUE; \ + } \ + if (COND) { \ + reset_conditions(); \ + break; \ + } \ + reset_conditions(); \ + if (MOCK_fail_nth == 0) { \ + break; \ + } \ + --MOCK_fail_nth; \ + if (MOCK_fail_nth == 0) { \ + return VALUE; \ + } \ + } while(0) + + +int GET_BOOL_NAME(open) = 0; +int MOCK_open(const char *pathname, int flags) +{ + HANDLE_FUNCTION(open, -1, 1); + return open(pathname, flags); +} + +int GET_BOOL_NAME(read) = 0; +ssize_t MOCK_read(int fd, void *buf, size_t count) +{ + HANDLE_FUNCTION(read, -1, 1); + return read(fd, buf, count); +} + +int GET_BOOL_NAME(BIO_flush) = 0; +int MOCK_BIO_flush(BIO *b) +{ + HANDLE_FUNCTION(BIO_flush, 0, 0); + return BIO_flush(b); +} + +int GET_BOOL_NAME(BIO_get_mem_data) = 0; +long MOCK_BIO_get_mem_data(BIO *b, char **pp) +{ + HANDLE_FUNCTION(BIO_get_mem_data, -1, 0); + return BIO_get_mem_data(b, pp); +} + +int GET_BOOL_NAME(BIO_new) = 0; +BIO *MOCK_BIO_new(const BIO_METHOD *type) +{ + HANDLE_FUNCTION(BIO_new, NULL, 0); + return BIO_new(type); +} + +int GET_BOOL_NAME(BIO_new_mem_buf) = 0; +BIO *MOCK_BIO_new_mem_buf(const void *buf, int len) +{ + HANDLE_FUNCTION(BIO_new_mem_buf, NULL, 0); + return BIO_new_mem_buf(buf, len); +} + +int GET_BOOL_NAME(BIO_read) = 0; +int MOCK_BIO_read(BIO *b, void *data, int dlen) +{ + HANDLE_FUNCTION(BIO_read, -1, 0); + return BIO_read(b, data, dlen); +} + +int GET_BOOL_NAME(BIO_reset) = 0; +int MOCK_BIO_reset(BIO *b) +{ + HANDLE_FUNCTION(BIO_reset, 0, 0); + BIO_reset_just_called = 1; + return BIO_reset(b); +} + +int GET_BOOL_NAME(BIO_write) = 0; +int MOCK_BIO_write(BIO *b, const void *data, int dlen) +{ + HANDLE_FUNCTION(BIO_write, -1, 0); + return BIO_write(b, data, dlen); +} + +int GET_BOOL_NAME(CMAC_CTX_new) = 0; +CMAC_CTX *MOCK_CMAC_CTX_new(void) +{ + HANDLE_FUNCTION(CMAC_CTX_new, NULL, 0); + return CMAC_CTX_new(); +} + +int GET_BOOL_NAME(CMAC_Init) = 0; +int MOCK_CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, const EVP_CIPHER *cipher, ENGINE *impl) +{ + HANDLE_FUNCTION(CMAC_Init, 0, 0); + return CMAC_Init(ctx, key, keylen, cipher, impl); +} + +int GET_BOOL_NAME(DES_random_key) = 0; +int MOCK_DES_random_key(DES_cblock *ret) +{ + HANDLE_FUNCTION(DES_random_key, 0, 0); + return DES_random_key(ret); +} + +int GET_BOOL_NAME(DH_KDF_X9_42) = 0; +int MOCK_DH_KDF_X9_42(unsigned char *out, size_t outlen, const unsigned char *Z, size_t Zlen, ASN1_OBJECT *key_oid, const unsigned char *ukm, size_t ukmlen, const EVP_MD *md) +{ + HANDLE_FUNCTION(DH_KDF_X9_42, 0, 0); + return DH_KDF_X9_42(out, outlen, Z, Zlen, key_oid, ukm, ukmlen, md); +} + +int GET_BOOL_NAME(ECDH_KDF_X9_62) = 0; +int MOCK_ECDH_KDF_X9_62(unsigned char *out, size_t outlen, const unsigned char *Z, size_t Zlen, const unsigned char *sinfo, size_t sinfolen, const EVP_MD *md) +{ + HANDLE_FUNCTION(ECDH_KDF_X9_62, 0, 0); + return ECDH_KDF_X9_62(out, outlen, Z, Zlen, sinfo, sinfolen, md); +} + +int GET_BOOL_NAME(EC_GROUP_get_asn1_flag) = 0; +int MOCK_EC_GROUP_get_asn1_flag(const EC_GROUP *group) +{ + HANDLE_FUNCTION(EC_GROUP_get_asn1_flag, 0, 0); + return EC_GROUP_get_asn1_flag(group); +} + +int GET_BOOL_NAME(EC_GROUP_get_curve_name) = 0; +int MOCK_EC_GROUP_get_curve_name(const EC_GROUP *group) +{ + HANDLE_FUNCTION(EC_GROUP_get_curve_name, 0, 0); + return EC_GROUP_get_curve_name(group); +} + +int GET_BOOL_NAME(EC_KEY_new) = 0; +EC_KEY *MOCK_EC_KEY_new() +{ + HANDLE_FUNCTION(EC_KEY_new, NULL, 0); + return EC_KEY_new(); +} + +int GET_BOOL_NAME(EC_KEY_set_group) = 0; +int MOCK_EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group) +{ + HANDLE_FUNCTION(EC_KEY_set_group, 0, 0); + return EC_KEY_set_group(key, group); +} + +int GET_BOOL_NAME(EVP_CIPHER_CTX_block_size) = 0; +int MOCK_EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx) +{ + HANDLE_FUNCTION(EVP_CIPHER_CTX_block_size, 0, 0); + return EVP_CIPHER_CTX_block_size(ctx); +} + +int GET_BOOL_NAME(EVP_CIPHER_CTX_cleanup) = 0; +int MOCK_EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c) +{ + HANDLE_FUNCTION(EVP_CIPHER_CTX_cleanup, 0, 0); + return EVP_CIPHER_CTX_cleanup(c); +} + +int GET_BOOL_NAME(EVP_CIPHER_CTX_ctrl) = 0; +int MOCK_EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) +{ + HANDLE_FUNCTION(EVP_CIPHER_CTX_ctrl, 0, 0); + return EVP_CIPHER_CTX_ctrl(ctx, type, arg, ptr); +} + +int GET_BOOL_NAME(EVP_CIPHER_CTX_new) = 0; +EVP_CIPHER_CTX *MOCK_EVP_CIPHER_CTX_new(void) +{ + HANDLE_FUNCTION(EVP_CIPHER_CTX_new, NULL, 0); + return EVP_CIPHER_CTX_new(); +} + +int GET_BOOL_NAME(EVP_CIPHER_CTX_set_key_length) = 0; +int MOCK_EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen) +{ + HANDLE_FUNCTION(EVP_CIPHER_CTX_set_key_length, 0, 0); + return EVP_CIPHER_CTX_set_key_length(x, keylen); +} + +int GET_BOOL_NAME(EVP_CIPHER_CTX_set_padding) = 0; +int MOCK_EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad) +{ + HANDLE_FUNCTION(EVP_CIPHER_CTX_set_padding, 0, 0); + return EVP_CIPHER_CTX_set_padding(c, pad); +} + +int GET_BOOL_NAME(EVP_CIPHER_iv_length) = 0; +int MOCK_EVP_CIPHER_iv_length(const EVP_CIPHER *cipher) +{ + HANDLE_FUNCTION(EVP_CIPHER_iv_length, -1, 0); + return EVP_CIPHER_iv_length(cipher); +} + +int GET_BOOL_NAME(EVP_CipherFinal) = 0; +int MOCK_EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl) +{ + HANDLE_FUNCTION(EVP_CipherFinal, 0, 0); + return EVP_CipherFinal(ctx, outm, outl); +} + +int GET_BOOL_NAME(EVP_CipherInit_ex) = 0; +int MOCK_EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, ENGINE *impl, const unsigned char *key, const unsigned char *iv, int enc) +{ + HANDLE_FUNCTION(EVP_CipherInit_ex, 0, 0); + return EVP_CipherInit_ex(ctx, type, impl, key, iv, enc); +} + +int GET_BOOL_NAME(EVP_CipherUpdate) = 0; +int MOCK_EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl) +{ + HANDLE_FUNCTION(EVP_CipherUpdate, 0, 0); + return EVP_CipherUpdate(ctx, out, outl, in, inl); +} + +int GET_BOOL_NAME(EVP_DigestFinal_ex) = 0; +int MOCK_EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s) +{ + HANDLE_FUNCTION(EVP_DigestFinal_ex, 0, 0); + return EVP_DigestFinal_ex(ctx, md, s); +} + +int GET_BOOL_NAME(EVP_DigestInit) = 0; +int MOCK_EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) +{ + HANDLE_FUNCTION(EVP_DigestInit, 0, 0); + return EVP_DigestInit(ctx, type); +} + +int GET_BOOL_NAME(EVP_DigestSignFinal) = 0; +int MOCK_EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen) +{ + HANDLE_FUNCTION(EVP_DigestSignFinal, 0, 0); + return EVP_DigestSignFinal(ctx, sigret, siglen); +} + +int GET_BOOL_NAME(EVP_DigestSignInit) = 0; +int MOCK_EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey) +{ + HANDLE_FUNCTION(EVP_DigestSignInit, 0, 0); + return EVP_DigestSignInit(ctx, pctx, type, e, pkey); +} + +int GET_BOOL_NAME(EVP_DigestSignUpdate) = 0; +int MOCK_EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt) +{ + HANDLE_FUNCTION(EVP_DigestSignUpdate, 0, 0); + return EVP_DigestSignUpdate(ctx, d, cnt); +} + +int GET_BOOL_NAME(EVP_DigestUpdate) = 0; +int MOCK_EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt) +{ + HANDLE_FUNCTION(EVP_DigestUpdate, 0, 0); + return EVP_DigestUpdate(ctx, d, cnt); +} + +int GET_BOOL_NAME(EVP_DigestVerifyFinal) = 0; +int MOCK_EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, size_t siglen) +{ + HANDLE_FUNCTION(EVP_DigestVerifyFinal, -1, 0); + return EVP_DigestVerifyFinal(ctx, sig, siglen); +} + +int GET_BOOL_NAME(EVP_DigestVerifyInit) = 0; +int MOCK_EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey) +{ + HANDLE_FUNCTION(EVP_DigestVerifyInit, 0, 0); + return EVP_DigestVerifyInit(ctx, pctx, type, e, pkey); +} + +int GET_BOOL_NAME(EVP_DigestVerifyUpdate) = 0; +int MOCK_EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt) +{ + HANDLE_FUNCTION(EVP_DigestVerifyUpdate, 0, 0); + return EVP_DigestVerifyUpdate(ctx, d, cnt); +} + +int GET_BOOL_NAME(EVP_MD_CTX_create) = 0; +EVP_MD_CTX *MOCK_EVP_MD_CTX_create() +{ + HANDLE_FUNCTION(EVP_MD_CTX_create, NULL, 0); + return EVP_MD_CTX_create(); +} + +int GET_BOOL_NAME(EVP_MD_CTX_pkey_ctx) = 0; +EVP_PKEY_CTX *MOCK_EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx) +{ + HANDLE_FUNCTION(EVP_MD_CTX_pkey_ctx, NULL, 0); + return EVP_MD_CTX_pkey_ctx(ctx); +} + +int GET_BOOL_NAME(EVP_MD_CTX_size) = 0; +int MOCK_EVP_MD_CTX_size(const EVP_MD_CTX *ctx) +{ + HANDLE_FUNCTION(EVP_MD_CTX_size, 0, 0); + return EVP_MD_CTX_size(ctx); +} + +int GET_BOOL_NAME(EVP_PKEY_CTX_ctrl) = 0; +int MOCK_EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, int p1, void *p2) +{ + HANDLE_FUNCTION(EVP_PKEY_CTX_ctrl, 0, 0); + return EVP_PKEY_CTX_ctrl(ctx, keytype, optype, cmd, p1, p2); +} + +int GET_BOOL_NAME(EVP_PKEY_CTX_get0_pkey) = 0; +EVP_PKEY *MOCK_EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx) +{ + HANDLE_FUNCTION(EVP_PKEY_CTX_get0_pkey, NULL, 0); + return EVP_PKEY_CTX_get0_pkey(ctx); +} + +int GET_BOOL_NAME(EVP_PKEY_CTX_new) = 0; +EVP_PKEY_CTX *MOCK_EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e) +{ + HANDLE_FUNCTION(EVP_PKEY_CTX_new, NULL, 0); + return EVP_PKEY_CTX_new(pkey, e); +} + +int GET_BOOL_NAME(EVP_PKEY_CTX_new_id) = 0; +EVP_PKEY_CTX *MOCK_EVP_PKEY_CTX_new_id(int id, ENGINE *e) +{ + HANDLE_FUNCTION(EVP_PKEY_CTX_new_id, NULL, 0); + return EVP_PKEY_CTX_new_id(id, e); +} + +int GET_BOOL_NAME(EVP_PKEY_CTX_set_dh_paramgen_generator) = 0; +int MOCK_EVP_PKEY_CTX_set_dh_paramgen_generator(EVP_PKEY_CTX *ctx, int gen) +{ + HANDLE_FUNCTION(EVP_PKEY_CTX_set_dh_paramgen_generator, 0, 0); + return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, gen); +} + +int GET_BOOL_NAME(EVP_PKEY_CTX_set_dh_paramgen_prime_len) = 0; +int MOCK_EVP_PKEY_CTX_set_dh_paramgen_prime_len(EVP_PKEY_CTX *ctx, int len) +{ + HANDLE_FUNCTION(EVP_PKEY_CTX_set_dh_paramgen_prime_len, 0, 0); + return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len); +} + +int GET_BOOL_NAME(EVP_PKEY_CTX_set_dsa_paramgen_bits) = 0; +int MOCK_EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX *ctx, int nbits) +{ + HANDLE_FUNCTION(EVP_PKEY_CTX_set_dsa_paramgen_bits, 0, 0); + return EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits); +} + +int GET_BOOL_NAME(EVP_PKEY_CTX_set_ec_param_enc) = 0; +int MOCK_EVP_PKEY_CTX_set_ec_param_enc(EVP_PKEY_CTX *ctx, int param_enc) +{ + HANDLE_FUNCTION(EVP_PKEY_CTX_set_ec_param_enc, 0, 0); + return EVP_PKEY_CTX_set_ec_param_enc(ctx, param_enc); +} + +int GET_BOOL_NAME(EVP_PKEY_CTX_set_ec_paramgen_curve_nid) = 0; +int MOCK_EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid) +{ + HANDLE_FUNCTION(EVP_PKEY_CTX_set_ec_paramgen_curve_nid, 0, 0); + return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid); +} + +int GET_BOOL_NAME(EVP_PKEY_CTX_set_rsa_keygen_bits) = 0; +int MOCK_EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int mbits) +{ + HANDLE_FUNCTION(EVP_PKEY_CTX_set_rsa_keygen_bits, 0, 0); + return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, mbits); +} + +int GET_BOOL_NAME(EVP_PKEY_CTX_set_rsa_padding) = 0; +int MOCK_EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad) +{ + HANDLE_FUNCTION(EVP_PKEY_CTX_set_rsa_padding, 0, 0); + return EVP_PKEY_CTX_set_rsa_padding(ctx, pad); +} + +int GET_BOOL_NAME(EVP_PKEY_assign) = 0; +int MOCK_EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) +{ + HANDLE_FUNCTION(EVP_PKEY_assign, 0, 0); + return EVP_PKEY_assign(pkey, type, key); +} + +int GET_BOOL_NAME(EVP_PKEY_assign_DH) = 0; +int MOCK_EVP_PKEY_assign_DH(EVP_PKEY *pkey, DH *key) +{ + HANDLE_FUNCTION(EVP_PKEY_assign_DH, 0, 0); + return EVP_PKEY_assign_DH(pkey, key); +} + +int GET_BOOL_NAME(EVP_PKEY_assign_DSA) = 0; +int MOCK_EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key) +{ + HANDLE_FUNCTION(EVP_PKEY_assign_DSA, 0, 0); + return EVP_PKEY_assign_DSA(pkey, key); +} + +int GET_BOOL_NAME(EVP_PKEY_assign_EC_KEY) = 0; +int MOCK_EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) +{ + HANDLE_FUNCTION(EVP_PKEY_assign_EC_KEY, 0, 0); + return EVP_PKEY_assign_EC_KEY(pkey, key); +} + +int GET_BOOL_NAME(EVP_PKEY_bits) = 0; +int MOCK_EVP_PKEY_bits(const EVP_PKEY *pkey) +{ + HANDLE_FUNCTION(EVP_PKEY_bits, 0, 0); + return EVP_PKEY_bits(pkey); +} + +int GET_BOOL_NAME(EVP_PKEY_decrypt_old) = 0; +int MOCK_EVP_PKEY_decrypt_old(unsigned char *dec_key, const unsigned char *enc_key, int enc_key_len, EVP_PKEY *private_key) +{ + HANDLE_FUNCTION(EVP_PKEY_decrypt_old, 0, 0); + return EVP_PKEY_decrypt_old(dec_key, enc_key, enc_key_len, private_key); +} + +int GET_BOOL_NAME(EVP_PKEY_derive) = 0; +int MOCK_EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) +{ + HANDLE_FUNCTION(EVP_PKEY_derive, 0, 0); + return EVP_PKEY_derive(ctx, key, keylen); +} + +int GET_BOOL_NAME(EVP_PKEY_derive_init) = 0; +int MOCK_EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) +{ + HANDLE_FUNCTION(EVP_PKEY_derive_init, 0, 0); + return EVP_PKEY_derive_init(ctx); +} + +int GET_BOOL_NAME(EVP_PKEY_derive_set_peer) = 0; +int MOCK_EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) +{ + HANDLE_FUNCTION(EVP_PKEY_derive_set_peer, 0, 0); + return EVP_PKEY_derive_set_peer(ctx, peer); +} + +int GET_BOOL_NAME(EVP_PKEY_encrypt_old) = 0; +int MOCK_EVP_PKEY_encrypt_old(unsigned char *enc_key, const unsigned char *key, int key_len, EVP_PKEY *pub_key) +{ + HANDLE_FUNCTION(EVP_PKEY_encrypt_old, 0, 0); + return EVP_PKEY_encrypt_old(enc_key, key, key_len, pub_key); +} + +int GET_BOOL_NAME(EVP_PKEY_keygen) = 0; +int MOCK_EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) +{ + HANDLE_FUNCTION(EVP_PKEY_keygen, 0, 0); + return EVP_PKEY_keygen(ctx, ppkey); +} + +int GET_BOOL_NAME(EVP_PKEY_keygen_init) = 0; +int MOCK_EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx) +{ + HANDLE_FUNCTION(EVP_PKEY_keygen_init, 0, 0); + return EVP_PKEY_keygen_init(ctx); +} + +int GET_BOOL_NAME(EVP_PKEY_new) = 0; +EVP_PKEY *MOCK_EVP_PKEY_new() +{ + HANDLE_FUNCTION(EVP_PKEY_new, NULL, 0); + return EVP_PKEY_new(); +} + +int GET_BOOL_NAME(EVP_PKEY_new_mac_key) = 0; +EVP_PKEY *MOCK_EVP_PKEY_new_mac_key(int type, ENGINE *e, const unsigned char *key, int keylen) +{ + HANDLE_FUNCTION(EVP_PKEY_new_mac_key, NULL, 0); + return EVP_PKEY_new_mac_key(type, e, key, keylen); +} + +int GET_BOOL_NAME(EVP_PKEY_paramgen) = 0; +int MOCK_EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) +{ + HANDLE_FUNCTION(EVP_PKEY_paramgen, 0, 0); + return EVP_PKEY_paramgen(ctx, ppkey); +} + +int GET_BOOL_NAME(EVP_PKEY_paramgen_init) = 0; +int MOCK_EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx) +{ + HANDLE_FUNCTION(EVP_PKEY_paramgen_init, 0, 0); + return EVP_PKEY_paramgen_init(ctx); +} + +int GET_BOOL_NAME(EVP_PKEY_size) = 0; +int MOCK_EVP_PKEY_size(EVP_PKEY *pkey) +{ + /* Cannot fail? */ + HANDLE_FUNCTION(EVP_PKEY_size, 0, 0); + return EVP_PKEY_size(pkey); +} + +int GET_BOOL_NAME(EVP_PKEY_up_ref) = 0; +int MOCK_EVP_PKEY_up_ref(EVP_PKEY *pkey) +{ + HANDLE_FUNCTION(EVP_PKEY_up_ref, 0, 0); + return EVP_PKEY_up_ref(pkey); +} + +int GET_BOOL_NAME(EVP_aes_128_cbc) = 0; +const EVP_CIPHER *MOCK_EVP_aes_128_cbc(void) +{ + HANDLE_FUNCTION(EVP_aes_128_cbc, NULL, 0); + return EVP_aes_128_cbc(); +} + +int GET_BOOL_NAME(EVP_aes_128_ccm) = 0; +const EVP_CIPHER *MOCK_EVP_aes_128_ccm(void) +{ + HANDLE_FUNCTION(EVP_aes_128_ccm, NULL, 0); + return EVP_aes_128_ccm(); +} + +#undef EVP_aes_128_cfb +int GET_BOOL_NAME(EVP_aes_128_cfb) = 0; +const EVP_CIPHER *MOCK_EVP_aes_128_cfb(void) +{ + HANDLE_FUNCTION(EVP_aes_128_cfb, NULL, 0); + return EVP_aes_128_cfb128(); +} + +int GET_BOOL_NAME(EVP_aes_128_cfb1) = 0; +const EVP_CIPHER *MOCK_EVP_aes_128_cfb1(void) +{ + HANDLE_FUNCTION(EVP_aes_128_cfb1, NULL, 0); + return EVP_aes_128_cfb1(); +} + +int GET_BOOL_NAME(EVP_aes_128_cfb8) = 0; +const EVP_CIPHER *MOCK_EVP_aes_128_cfb8(void) +{ + HANDLE_FUNCTION(EVP_aes_128_cfb8, NULL, 0); + return EVP_aes_128_cfb8(); +} + +int GET_BOOL_NAME(EVP_aes_128_ctr) = 0; +const EVP_CIPHER *MOCK_EVP_aes_128_ctr(void) +{ + HANDLE_FUNCTION(EVP_aes_128_ctr, NULL, 0); + return EVP_aes_128_ctr(); +} + +int GET_BOOL_NAME(EVP_aes_128_ecb) = 0; +const EVP_CIPHER *MOCK_EVP_aes_128_ecb(void) +{ + HANDLE_FUNCTION(EVP_aes_128_ecb, NULL, 0); + return EVP_aes_128_ecb(); +} + +int GET_BOOL_NAME(EVP_aes_128_gcm) = 0; +const EVP_CIPHER *MOCK_EVP_aes_128_gcm(void) +{ + HANDLE_FUNCTION(EVP_aes_128_gcm, NULL, 0); + return EVP_aes_128_gcm(); +} + +int GET_BOOL_NAME(EVP_aes_128_ofb) = 0; +const EVP_CIPHER *MOCK_EVP_aes_128_ofb(void) +{ + HANDLE_FUNCTION(EVP_aes_128_ofb, NULL, 0); + return EVP_aes_128_ofb(); +} + +int GET_BOOL_NAME(EVP_aes_128_wrap) = 0; +const EVP_CIPHER *MOCK_EVP_aes_128_wrap(void) +{ + HANDLE_FUNCTION(EVP_aes_128_wrap, NULL, 0); + return EVP_aes_128_wrap(); +} + +int GET_BOOL_NAME(EVP_aes_192_cbc) = 0; +const EVP_CIPHER *MOCK_EVP_aes_192_cbc(void) +{ + HANDLE_FUNCTION(EVP_aes_192_cbc, NULL, 0); + return EVP_aes_192_cbc(); +} + +int GET_BOOL_NAME(EVP_aes_192_ccm) = 0; +const EVP_CIPHER *MOCK_EVP_aes_192_ccm(void) +{ + HANDLE_FUNCTION(EVP_aes_192_ccm, NULL, 0); + return EVP_aes_192_ccm(); +} + +#undef EVP_aes_192_cfb +int GET_BOOL_NAME(EVP_aes_192_cfb) = 0; +const EVP_CIPHER *MOCK_EVP_aes_192_cfb(void) +{ + HANDLE_FUNCTION(EVP_aes_192_cfb, NULL, 0); + return EVP_aes_192_cfb128(); +} + +int GET_BOOL_NAME(EVP_aes_192_cfb1) = 0; +const EVP_CIPHER *MOCK_EVP_aes_192_cfb1(void) +{ + HANDLE_FUNCTION(EVP_aes_192_cfb1, NULL, 0); + return EVP_aes_192_cfb1(); +} + +int GET_BOOL_NAME(EVP_aes_192_cfb8) = 0; +const EVP_CIPHER *MOCK_EVP_aes_192_cfb8(void) +{ + HANDLE_FUNCTION(EVP_aes_192_cfb8, NULL, 0); + return EVP_aes_192_cfb8(); +} + +int GET_BOOL_NAME(EVP_aes_192_ctr) = 0; +const EVP_CIPHER *MOCK_EVP_aes_192_ctr(void) +{ + HANDLE_FUNCTION(EVP_aes_192_ctr, NULL, 0); + return EVP_aes_192_ctr(); +} + +int GET_BOOL_NAME(EVP_aes_192_ecb) = 0; +const EVP_CIPHER *MOCK_EVP_aes_192_ecb(void) +{ + HANDLE_FUNCTION(EVP_aes_192_ecb, NULL, 0); + return EVP_aes_192_ecb(); +} + +int GET_BOOL_NAME(EVP_aes_192_gcm) = 0; +const EVP_CIPHER *MOCK_EVP_aes_192_gcm(void) +{ + HANDLE_FUNCTION(EVP_aes_192_gcm, NULL, 0); + return EVP_aes_192_gcm(); +} + +int GET_BOOL_NAME(EVP_aes_192_ofb) = 0; +const EVP_CIPHER *MOCK_EVP_aes_192_ofb(void) +{ + HANDLE_FUNCTION(EVP_aes_192_ofb, NULL, 0); + return EVP_aes_192_ofb(); +} + +int GET_BOOL_NAME(EVP_aes_192_wrap) = 0; +const EVP_CIPHER *MOCK_EVP_aes_192_wrap(void) +{ + HANDLE_FUNCTION(EVP_aes_192_wrap, NULL, 0); + return EVP_aes_192_wrap(); +} + +int GET_BOOL_NAME(EVP_aes_256_cbc) = 0; +const EVP_CIPHER *MOCK_EVP_aes_256_cbc() +{ + HANDLE_FUNCTION(EVP_aes_256_cbc, NULL, 0); + return EVP_aes_256_cbc(); +} + +int GET_BOOL_NAME(EVP_aes_256_ccm) = 0; +const EVP_CIPHER *MOCK_EVP_aes_256_ccm(void) +{ + HANDLE_FUNCTION(EVP_aes_256_ccm, NULL, 0); + return EVP_aes_256_ccm(); +} + +#undef EVP_aes_256_cfb +int GET_BOOL_NAME(EVP_aes_256_cfb) = 0; +const EVP_CIPHER *MOCK_EVP_aes_256_cfb(void) +{ + HANDLE_FUNCTION(EVP_aes_256_cfb, NULL, 0); + return EVP_aes_256_cfb128(); +} + +int GET_BOOL_NAME(EVP_aes_256_cfb1) = 0; +const EVP_CIPHER *MOCK_EVP_aes_256_cfb1(void) +{ + HANDLE_FUNCTION(EVP_aes_256_cfb1, NULL, 0); + return EVP_aes_256_cfb1(); +} + +int GET_BOOL_NAME(EVP_aes_256_cfb8) = 0; +const EVP_CIPHER *MOCK_EVP_aes_256_cfb8(void) +{ + HANDLE_FUNCTION(EVP_aes_256_cfb8, NULL, 0); + return EVP_aes_256_cfb8(); +} + +int GET_BOOL_NAME(EVP_aes_256_ctr) = 0; +const EVP_CIPHER *MOCK_EVP_aes_256_ctr(void) +{ + HANDLE_FUNCTION(EVP_aes_256_ctr, NULL, 0); + return EVP_aes_256_ctr(); +} + +int GET_BOOL_NAME(EVP_aes_256_ecb) = 0; +const EVP_CIPHER *MOCK_EVP_aes_256_ecb(void) +{ + HANDLE_FUNCTION(EVP_aes_256_ecb, NULL, 0); + return EVP_aes_256_ecb(); +} + +int GET_BOOL_NAME(EVP_aes_256_gcm) = 0; +const EVP_CIPHER *MOCK_EVP_aes_256_gcm(void) +{ + HANDLE_FUNCTION(EVP_aes_256_gcm, NULL, 0); + return EVP_aes_256_gcm(); +} + +int GET_BOOL_NAME(EVP_aes_256_ofb) = 0; +const EVP_CIPHER *MOCK_EVP_aes_256_ofb(void) +{ + HANDLE_FUNCTION(EVP_aes_256_ofb, NULL, 0); + return EVP_aes_256_ofb(); +} + +int GET_BOOL_NAME(EVP_aes_256_wrap) = 0; +const EVP_CIPHER *MOCK_EVP_aes_256_wrap(void) +{ + HANDLE_FUNCTION(EVP_aes_256_wrap, NULL, 0); + return EVP_aes_256_wrap(); +} + +int GET_BOOL_NAME(EVP_cast5_cbc) = 0; +const EVP_CIPHER *MOCK_EVP_cast5_cbc(void) +{ + HANDLE_FUNCTION(EVP_cast5_cbc, NULL, 0); + return EVP_cast5_cbc(); +} + +#undef EVP_cast5_cfb +int GET_BOOL_NAME(EVP_cast5_cfb) = 0; +const EVP_CIPHER *MOCK_EVP_cast5_cfb(void) +{ + HANDLE_FUNCTION(EVP_cast5_cfb, NULL, 0); + return EVP_cast5_cfb64(); +} + +int GET_BOOL_NAME(EVP_cast5_ecb) = 0; +const EVP_CIPHER *MOCK_EVP_cast5_ecb(void) +{ + HANDLE_FUNCTION(EVP_cast5_ecb, NULL, 0); + return EVP_cast5_ecb(); +} + +int GET_BOOL_NAME(EVP_cast5_ofb) = 0; +const EVP_CIPHER *MOCK_EVP_cast5_ofb(void) +{ + HANDLE_FUNCTION(EVP_cast5_ofb, NULL, 0); + return EVP_cast5_ofb(); +} + +int GET_BOOL_NAME(EVP_des_cbc) = 0; +const EVP_CIPHER *MOCK_EVP_des_cbc(void) +{ + HANDLE_FUNCTION(EVP_des_cbc, NULL, 0); + return EVP_des_cbc(); +} + +#undef EVP_des_cfb +int GET_BOOL_NAME(EVP_des_cfb) = 0; +const EVP_CIPHER *MOCK_EVP_des_cfb(void) +{ + HANDLE_FUNCTION(EVP_des_cfb, NULL, 0); + return EVP_des_cfb64(); +} + +int GET_BOOL_NAME(EVP_des_cfb1) = 0; +const EVP_CIPHER *MOCK_EVP_des_cfb1(void) +{ + HANDLE_FUNCTION(EVP_des_cfb1, NULL, 0); + return EVP_des_cfb1(); +} + +int GET_BOOL_NAME(EVP_des_cfb8) = 0; +const EVP_CIPHER *MOCK_EVP_des_cfb8(void) +{ + HANDLE_FUNCTION(EVP_des_cfb8, NULL, 0); + return EVP_des_cfb8(); +} + +int GET_BOOL_NAME(EVP_des_ecb) = 0; +const EVP_CIPHER *MOCK_EVP_des_ecb(void) +{ + HANDLE_FUNCTION(EVP_des_ecb, NULL, 0); + return EVP_des_ecb(); +} + +int GET_BOOL_NAME(EVP_des_ede3_cbc) = 0; +const EVP_CIPHER *MOCK_EVP_des_ede3_cbc(void) +{ + HANDLE_FUNCTION(EVP_des_ede3_cbc, NULL, 0); + return EVP_des_ede3_cbc(); +} + +#undef EVP_des_ede3_cfb +int GET_BOOL_NAME(EVP_des_ede3_cfb) = 0; +const EVP_CIPHER *MOCK_EVP_des_ede3_cfb(void) +{ + HANDLE_FUNCTION(EVP_des_ede3_cfb, NULL, 0); + return EVP_des_ede3_cfb64(); +} + +int GET_BOOL_NAME(EVP_des_ede3_cfb1) = 0; +const EVP_CIPHER *MOCK_EVP_des_ede3_cfb1(void) +{ + HANDLE_FUNCTION(EVP_des_ede3_cfb1, NULL, 0); + return EVP_des_ede3_cfb1(); +} + +int GET_BOOL_NAME(EVP_des_ede3_cfb8) = 0; +const EVP_CIPHER *MOCK_EVP_des_ede3_cfb8(void) +{ + HANDLE_FUNCTION(EVP_des_ede3_cfb8, NULL, 0); + return EVP_des_ede3_cfb8(); +} + +int GET_BOOL_NAME(EVP_des_ede3_ecb) = 0; +const EVP_CIPHER *MOCK_EVP_des_ede3_ecb(void) +{ + HANDLE_FUNCTION(EVP_des_ede3_ecb, NULL, 0); + return EVP_des_ede3_ecb(); +} + +int GET_BOOL_NAME(EVP_des_ede3_ofb) = 0; +const EVP_CIPHER *MOCK_EVP_des_ede3_ofb(void) +{ + HANDLE_FUNCTION(EVP_des_ede3_ofb, NULL, 0); + return EVP_des_ede3_ofb(); +} + +int GET_BOOL_NAME(EVP_des_ede3_wrap) = 0; +const EVP_CIPHER *MOCK_EVP_des_ede3_wrap(void) +{ + HANDLE_FUNCTION(EVP_des_ede3_wrap, NULL, 0); + return EVP_des_ede3_wrap(); +} + +int GET_BOOL_NAME(EVP_des_ede_cbc) = 0; +const EVP_CIPHER *MOCK_EVP_des_ede_cbc(void) +{ + HANDLE_FUNCTION(EVP_des_ede_cbc, NULL, 0); + return EVP_des_ede_cbc(); +} + +#undef EVP_des_ede_cfb +int GET_BOOL_NAME(EVP_des_ede_cfb) = 0; +const EVP_CIPHER *MOCK_EVP_des_ede_cfb(void) +{ + HANDLE_FUNCTION(EVP_des_ede_cfb, NULL, 0); + return EVP_des_ede_cfb64(); +} + +int GET_BOOL_NAME(EVP_des_ede_ecb) = 0; +const EVP_CIPHER *MOCK_EVP_des_ede_ecb(void) +{ + HANDLE_FUNCTION(EVP_des_ede_ecb, NULL, 0); + return EVP_des_ede_ecb(); +} + +int GET_BOOL_NAME(EVP_des_ede_ofb) = 0; +const EVP_CIPHER *MOCK_EVP_des_ede_ofb(void) +{ + HANDLE_FUNCTION(EVP_des_ede_ofb, NULL, 0); + return EVP_des_ede_ofb(); +} + +int GET_BOOL_NAME(EVP_des_ofb) = 0; +const EVP_CIPHER *MOCK_EVP_des_ofb(void) +{ + HANDLE_FUNCTION(EVP_des_ofb, NULL, 0); + return EVP_des_ofb(); +} + +int GET_BOOL_NAME(EVP_md5) = 0; +const EVP_MD *MOCK_EVP_md5(void) +{ + HANDLE_FUNCTION(EVP_md5, NULL, 0); + return EVP_md5(); +} + +int GET_BOOL_NAME(EVP_rc2_cbc) = 0; +const EVP_CIPHER *MOCK_EVP_rc2_cbc(void) +{ + HANDLE_FUNCTION(EVP_rc2_cbc, NULL, 0); + return EVP_rc2_cbc(); +} + +#undef EVP_rc2_cfb +int GET_BOOL_NAME(EVP_rc2_cfb) = 0; +const EVP_CIPHER *MOCK_EVP_rc2_cfb(void) +{ + HANDLE_FUNCTION(EVP_rc2_cfb, NULL, 0); + return EVP_rc2_cfb64(); +} + +int GET_BOOL_NAME(EVP_rc2_ecb) = 0; +const EVP_CIPHER *MOCK_EVP_rc2_ecb(void) +{ + HANDLE_FUNCTION(EVP_rc2_ecb, NULL, 0); + return EVP_rc2_ecb(); +} + +int GET_BOOL_NAME(EVP_rc2_ofb) = 0; +const EVP_CIPHER *MOCK_EVP_rc2_ofb(void) +{ + HANDLE_FUNCTION(EVP_rc2_ofb, NULL, 0); + return EVP_rc2_ofb(); +} + +int GET_BOOL_NAME(EVP_rc4) = 0; +const EVP_CIPHER *MOCK_EVP_rc4(void) +{ + HANDLE_FUNCTION(EVP_rc4, NULL, 0); + return EVP_rc4(); +} + +int GET_BOOL_NAME(EVP_sha1) = 0; +const EVP_MD *MOCK_EVP_sha1(void) +{ + HANDLE_FUNCTION(EVP_sha1, NULL, 0); + return EVP_sha1(); +} + +int GET_BOOL_NAME(EVP_sha224) = 0; +const EVP_MD *MOCK_EVP_sha224(void) +{ + HANDLE_FUNCTION(EVP_sha224, NULL, 0); + return EVP_sha224(); +} + +int GET_BOOL_NAME(EVP_sha256) = 0; +const EVP_MD *MOCK_EVP_sha256(void) +{ + HANDLE_FUNCTION(EVP_sha256, NULL, 0); + return EVP_sha256(); +} + +int GET_BOOL_NAME(EVP_sha384) = 0; +const EVP_MD *MOCK_EVP_sha384(void) +{ + HANDLE_FUNCTION(EVP_sha384, NULL, 0); + return EVP_sha384(); +} + +int GET_BOOL_NAME(EVP_sha512) = 0; +const EVP_MD *MOCK_EVP_sha512(void) +{ + HANDLE_FUNCTION(EVP_sha512, NULL, 0); + return EVP_sha512(); +} + +int GET_BOOL_NAME(OPENSSL_malloc) = 0; +void *MOCK_OPENSSL_malloc(size_t num) +{ + HANDLE_FUNCTION(OPENSSL_malloc, NULL, 0); + return OPENSSL_malloc(num); +} + +int GET_BOOL_NAME(OPENSSL_realloc) = 0; +void *MOCK_OPENSSL_realloc(void *addr, size_t num) +{ + HANDLE_FUNCTION(OPENSSL_realloc, NULL, 0); + return OPENSSL_realloc(addr, num); +} + +int GET_BOOL_NAME(PEM_read_bio_PUBKEY) = 0; +EVP_PKEY *MOCK_PEM_read_bio_PUBKEY(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u) +{ + HANDLE_FUNCTION(PEM_read_bio_PUBKEY, NULL, BIO_reset_just_called); + return PEM_read_bio_PUBKEY(bp, x, cb, u); +} + +int GET_BOOL_NAME(PEM_read_bio_Parameters) = 0; +EVP_PKEY *MOCK_PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x) +{ + HANDLE_FUNCTION(PEM_read_bio_Parameters, NULL, BIO_reset_just_called); + return PEM_read_bio_Parameters(bp, x); +} + +int GET_BOOL_NAME(PEM_read_bio_PrivateKey) = 0; +EVP_PKEY *MOCK_PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u) +{ + HANDLE_FUNCTION(PEM_read_bio_PrivateKey, NULL, BIO_reset_just_called); + return PEM_read_bio_PrivateKey(bp, x, cb, u); +} + +int GET_BOOL_NAME(PEM_read_bio_X509) = 0; +X509 *MOCK_PEM_read_bio_X509(BIO *bp, X509 **x, pem_password_cb *cb, void *u) +{ + HANDLE_FUNCTION(PEM_read_bio_X509, NULL, BIO_reset_just_called); + return PEM_read_bio_X509(bp, x, cb, u); +} + +int GET_BOOL_NAME(PEM_write_bio_PKCS8PrivateKey) = 0; +int MOCK_PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cb, void *u) +{ + HANDLE_FUNCTION(PEM_write_bio_PKCS8PrivateKey, 0, 0); + return PEM_write_bio_PKCS8PrivateKey(bp, x, enc, kstr, klen, cb, u); +} + +int GET_BOOL_NAME(PEM_write_bio_PUBKEY) = 0; +int MOCK_PEM_write_bio_PUBKEY(BIO *bp, EVP_PKEY *x) +{ + HANDLE_FUNCTION(PEM_write_bio_PUBKEY, 0, 0); + return PEM_write_bio_PUBKEY(bp, x); +} + +int GET_BOOL_NAME(PEM_write_bio_Parameters) = 0; +int MOCK_PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x) +{ + HANDLE_FUNCTION(PEM_write_bio_Parameters, 0, 0); + return PEM_write_bio_Parameters(bp, x); +} + +int GET_BOOL_NAME(PEM_write_bio_PrivateKey) = 0; +int MOCK_PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, void *u) +{ + HANDLE_FUNCTION(PEM_write_bio_PrivateKey, 0, 0); + return PEM_write_bio_PrivateKey(bp, x, enc, kstr, klen, cb, u); +} + +int GET_BOOL_NAME(PKCS5_PBKDF2_HMAC); +int MOCK_PKCS5_PBKDF2_HMAC(const char *pass, int passlen, const unsigned char *salt, int saltlen, int iter, const EVP_MD *digest, int keylen, unsigned char *out) +{ + HANDLE_FUNCTION(PKCS5_PBKDF2_HMAC, 0, 0); + return PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, digest, keylen, out); +} + +int GET_BOOL_NAME(RAND_bytes) = 0; +int MOCK_RAND_bytes(unsigned char *buf, int num) +{ + HANDLE_FUNCTION(RAND_bytes, 0, 0); + return RAND_bytes(buf, num); +} + +int GET_BOOL_NAME(RSA_private_decrypt) = 0; +int MOCK_RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) +{ + HANDLE_FUNCTION(RSA_private_decrypt, -1, 0); + return RSA_private_decrypt(flen, from, to, rsa, padding); +} + +int GET_BOOL_NAME(RSA_private_encrypt) = 0; +int MOCK_RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) +{ + HANDLE_FUNCTION(RSA_private_encrypt, -1, 0); + return RSA_private_encrypt(flen, from, to, rsa, padding); +} + +int GET_BOOL_NAME(RSA_public_decrypt) = 0; +int MOCK_RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) +{ + HANDLE_FUNCTION(RSA_public_decrypt, -1, 0); + return RSA_public_decrypt(flen, from, to, rsa, padding); +} + +int GET_BOOL_NAME(RSA_public_encrypt) = 0; +int MOCK_RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) +{ + HANDLE_FUNCTION(RSA_public_encrypt, -1, 0); + return RSA_public_encrypt(flen, from, to, rsa, padding); +} + +int GET_BOOL_NAME(X509_get_pubkey) = 0; +EVP_PKEY *MOCK_X509_get_pubkey(X509 *x) +{ + HANDLE_FUNCTION(X509_get_pubkey, NULL, 0); + return X509_get_pubkey(x); +} + +int GET_BOOL_NAME(d2i_DHparams_bio) = 0; +DH *MOCK_d2i_DHparams_bio(BIO *bp, DH **x) +{ + HANDLE_FUNCTION(d2i_DHparams_bio, NULL, BIO_reset_just_called); + return d2i_DHparams_bio(bp, x); +} + +int GET_BOOL_NAME(d2i_DSAparams_bio) = 0; +DSA *MOCK_d2i_DSAparams_bio(BIO *bp, DSA **x) +{ + HANDLE_FUNCTION(d2i_DSAparams_bio, NULL, BIO_reset_just_called); + return d2i_DSAparams_bio(bp, x); +} + +int GET_BOOL_NAME(d2i_ECPKParameters_bio) = 0; +EC_GROUP *MOCK_d2i_ECPKParameters_bio(BIO *bp, EC_GROUP **x) +{ + HANDLE_FUNCTION(d2i_ECPKParameters_bio, NULL, BIO_reset_just_called); + return d2i_ECPKParameters_bio(bp, x); +} + +int GET_BOOL_NAME(d2i_PKCS8PrivateKey_bio) = 0; +EVP_PKEY *MOCK_d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u) +{ + HANDLE_FUNCTION(d2i_PKCS8PrivateKey_bio, NULL, BIO_reset_just_called); + return d2i_PKCS8PrivateKey_bio(bp, x, cb, u); +} + +int GET_BOOL_NAME(d2i_PUBKEY_bio) = 0; +EVP_PKEY *MOCK_d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a) +{ + HANDLE_FUNCTION(d2i_PUBKEY_bio, NULL, BIO_reset_just_called); + return d2i_PUBKEY_bio(bp, a); +} + +int GET_BOOL_NAME(d2i_PrivateKey_bio) = 0; +EVP_PKEY *MOCK_d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a) +{ + HANDLE_FUNCTION(d2i_PrivateKey_bio, NULL, BIO_reset_just_called); + return d2i_PrivateKey_bio(bp, a); +} + +int GET_BOOL_NAME(d2i_X509_bio) = 0; +X509 *MOCK_d2i_X509_bio(BIO *bp, X509 **x509) +{ + HANDLE_FUNCTION(d2i_X509_bio, NULL, BIO_reset_just_called); + return d2i_X509_bio(bp, x509); +} + +int GET_BOOL_NAME(i2d_DHparams_bio) = 0; +int MOCK_i2d_DHparams_bio(BIO *bp, const DH *x) +{ + HANDLE_FUNCTION(i2d_DHparams_bio, 0, 0); + return i2d_DHparams_bio(bp, x); +} + +int GET_BOOL_NAME(i2d_DSAparams_bio) = 0; +int MOCK_i2d_DSAparams_bio(BIO *bp, const DSA *x) +{ + HANDLE_FUNCTION(i2d_DSAparams_bio, 0, 0); + return i2d_DSAparams_bio(bp, x); +} + +int GET_BOOL_NAME(i2d_ECPKParameters_bio) = 0; +int MOCK_i2d_ECPKParameters_bio(BIO *bp, const EC_GROUP *x) +{ + HANDLE_FUNCTION(i2d_ECPKParameters_bio, 0, 0); + return i2d_ECPKParameters_bio(bp, x); +} + +int GET_BOOL_NAME(i2d_PKCS8PrivateKey_bio) = 0; +int MOCK_i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cb, void *u) +{ + HANDLE_FUNCTION(i2d_PKCS8PrivateKey_bio, 0, 0); + return i2d_PKCS8PrivateKey_bio(bp, x, enc, kstr, klen, cb, u); +} + +int GET_BOOL_NAME(i2d_PUBKEY_bio) = 0; +int MOCK_i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey) +{ + HANDLE_FUNCTION(i2d_PUBKEY_bio, 0, 0); + return i2d_PUBKEY_bio(bp, pkey); +} + +int GET_BOOL_NAME(i2d_PrivateKey_bio) = 0; +int MOCK_i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey) +{ + HANDLE_FUNCTION(i2d_PrivateKey_bio, 0, 0); + return i2d_PrivateKey_bio(bp, pkey); +} diff --git a/tests/openssl_mock_impl.h b/tests/openssl_mock_impl.h new file mode 100644 index 0000000..c0c089c --- /dev/null +++ b/tests/openssl_mock_impl.h @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Pawelczyk + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file openssl_mock_impl.h + * @brief + */ + +#ifndef OPENSSL_MOCK_IMPL_H +#define OPENSSL_MOCK_IMPL_H + +#include "openssl_mock_functions.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GET_BOOL_NAME(FNAME) MOCK_fail_##FNAME + +extern unsigned MOCK_fail_nth; + +extern int GET_BOOL_NAME(open); +extern int GET_BOOL_NAME(read); +extern int GET_BOOL_NAME(BIO_flush); +extern int GET_BOOL_NAME(BIO_flush); +extern int GET_BOOL_NAME(BIO_get_mem_data); +extern int GET_BOOL_NAME(BIO_new); +extern int GET_BOOL_NAME(BIO_new_mem_buf); +extern int GET_BOOL_NAME(BIO_read); +extern int GET_BOOL_NAME(BIO_reset); +extern int GET_BOOL_NAME(BIO_write); +extern int GET_BOOL_NAME(CMAC_CTX_new); +extern int GET_BOOL_NAME(CMAC_Init); +extern int GET_BOOL_NAME(DES_random_key); +extern int GET_BOOL_NAME(DH_KDF_X9_42); +extern int GET_BOOL_NAME(ECDH_KDF_X9_62); +extern int GET_BOOL_NAME(EC_GROUP_get_asn1_flag); +extern int GET_BOOL_NAME(EC_GROUP_get_curve_name); +extern int GET_BOOL_NAME(EC_KEY_new); +extern int GET_BOOL_NAME(EC_KEY_set_group); +extern int GET_BOOL_NAME(EVP_CIPHER_CTX_block_size); +extern int GET_BOOL_NAME(EVP_CIPHER_CTX_cleanup); +extern int GET_BOOL_NAME(EVP_CIPHER_CTX_ctrl); +extern int GET_BOOL_NAME(EVP_CIPHER_CTX_new); +extern int GET_BOOL_NAME(EVP_CIPHER_CTX_set_key_length); +extern int GET_BOOL_NAME(EVP_CIPHER_CTX_set_padding); +extern int GET_BOOL_NAME(EVP_CIPHER_iv_length); +extern int GET_BOOL_NAME(EVP_CipherFinal); +extern int GET_BOOL_NAME(EVP_CipherUpdate); +extern int GET_BOOL_NAME(EVP_DigestFinal_ex); +extern int GET_BOOL_NAME(EVP_DigestInit); +extern int GET_BOOL_NAME(EVP_DigestSignFinal); +extern int GET_BOOL_NAME(EVP_DigestSignInit); +extern int GET_BOOL_NAME(EVP_DigestSignUpdate); +extern int GET_BOOL_NAME(EVP_DigestUpdate); +extern int GET_BOOL_NAME(EVP_DigestVerifyFinal); +extern int GET_BOOL_NAME(EVP_DigestVerifyInit); +extern int GET_BOOL_NAME(EVP_DigestVerifyUpdate); +extern int GET_BOOL_NAME(EVP_MD_CTX_create); +extern int GET_BOOL_NAME(EVP_MD_CTX_pkey_ctx); +extern int GET_BOOL_NAME(EVP_MD_CTX_size); +extern int GET_BOOL_NAME(EVP_PKEY_CTX_ctrl); +extern int GET_BOOL_NAME(EVP_PKEY_CTX_get0_pkey); +extern int GET_BOOL_NAME(EVP_PKEY_CTX_new); +extern int GET_BOOL_NAME(EVP_PKEY_CTX_new_id); +extern int GET_BOOL_NAME(EVP_PKEY_CTX_set_dh_paramgen_generator); +extern int GET_BOOL_NAME(EVP_PKEY_CTX_set_dh_paramgen_prime_len); +extern int GET_BOOL_NAME(EVP_PKEY_CTX_set_dsa_paramgen_bits); +extern int GET_BOOL_NAME(EVP_PKEY_CTX_set_ec_param_enc); +extern int GET_BOOL_NAME(EVP_PKEY_CTX_set_ec_paramgen_curve_nid); +extern int GET_BOOL_NAME(EVP_PKEY_CTX_set_rsa_keygen_bits); +extern int GET_BOOL_NAME(EVP_PKEY_CTX_set_rsa_padding); +extern int GET_BOOL_NAME(EVP_PKEY_assign); +extern int GET_BOOL_NAME(EVP_PKEY_assign_DH); +extern int GET_BOOL_NAME(EVP_PKEY_assign_DSA); +extern int GET_BOOL_NAME(EVP_PKEY_assign_EC_KEY); +extern int GET_BOOL_NAME(EVP_PKEY_bits); +extern int GET_BOOL_NAME(EVP_PKEY_decrypt_old); +extern int GET_BOOL_NAME(EVP_PKEY_derive); +extern int GET_BOOL_NAME(EVP_PKEY_derive_init); +extern int GET_BOOL_NAME(EVP_PKEY_derive_set_peer); +extern int GET_BOOL_NAME(EVP_PKEY_encrypt_old); +extern int GET_BOOL_NAME(EVP_PKEY_keygen); +extern int GET_BOOL_NAME(EVP_PKEY_keygen_init); +extern int GET_BOOL_NAME(EVP_PKEY_new); +extern int GET_BOOL_NAME(EVP_PKEY_new_mac_key); +extern int GET_BOOL_NAME(EVP_PKEY_paramgen); +extern int GET_BOOL_NAME(EVP_PKEY_paramgen_init); +extern int GET_BOOL_NAME(EVP_PKEY_size); +extern int GET_BOOL_NAME(EVP_PKEY_up_ref); +extern int GET_BOOL_NAME(EVP_aes_128_cbc); +extern int GET_BOOL_NAME(EVP_aes_128_ccm); +extern int GET_BOOL_NAME(EVP_aes_128_cfb); +extern int GET_BOOL_NAME(EVP_aes_128_cfb1); +extern int GET_BOOL_NAME(EVP_aes_128_cfb8); +extern int GET_BOOL_NAME(EVP_aes_128_ctr); +extern int GET_BOOL_NAME(EVP_aes_128_ecb); +extern int GET_BOOL_NAME(EVP_aes_128_gcm); +extern int GET_BOOL_NAME(EVP_aes_128_ofb); +extern int GET_BOOL_NAME(EVP_aes_128_wrap); +extern int GET_BOOL_NAME(EVP_aes_192_cbc); +extern int GET_BOOL_NAME(EVP_aes_192_ccm); +extern int GET_BOOL_NAME(EVP_aes_192_cfb); +extern int GET_BOOL_NAME(EVP_aes_192_cfb1); +extern int GET_BOOL_NAME(EVP_aes_192_cfb8); +extern int GET_BOOL_NAME(EVP_aes_192_ctr); +extern int GET_BOOL_NAME(EVP_aes_192_ecb); +extern int GET_BOOL_NAME(EVP_aes_192_gcm); +extern int GET_BOOL_NAME(EVP_aes_192_ofb); +extern int GET_BOOL_NAME(EVP_aes_192_wrap); +extern int GET_BOOL_NAME(EVP_aes_256_cbc); +extern int GET_BOOL_NAME(EVP_aes_256_ccm); +extern int GET_BOOL_NAME(EVP_aes_256_cfb); +extern int GET_BOOL_NAME(EVP_aes_256_cfb1); +extern int GET_BOOL_NAME(EVP_aes_256_cfb8); +extern int GET_BOOL_NAME(EVP_aes_256_ctr); +extern int GET_BOOL_NAME(EVP_aes_256_ecb); +extern int GET_BOOL_NAME(EVP_aes_256_gcm); +extern int GET_BOOL_NAME(EVP_aes_256_ofb); +extern int GET_BOOL_NAME(EVP_aes_256_wrap); +extern int GET_BOOL_NAME(EVP_cast5_cbc); +extern int GET_BOOL_NAME(EVP_cast5_cfb); +extern int GET_BOOL_NAME(EVP_cast5_ecb); +extern int GET_BOOL_NAME(EVP_cast5_ofb); +extern int GET_BOOL_NAME(EVP_des_cbc); +extern int GET_BOOL_NAME(EVP_des_cfb); +extern int GET_BOOL_NAME(EVP_des_cfb1); +extern int GET_BOOL_NAME(EVP_des_cfb8); +extern int GET_BOOL_NAME(EVP_des_ecb); +extern int GET_BOOL_NAME(EVP_des_ede3_cbc); +extern int GET_BOOL_NAME(EVP_des_ede3_cfb); +extern int GET_BOOL_NAME(EVP_des_ede3_cfb1); +extern int GET_BOOL_NAME(EVP_des_ede3_cfb8); +extern int GET_BOOL_NAME(EVP_des_ede3_ecb); +extern int GET_BOOL_NAME(EVP_des_ede3_ofb); +extern int GET_BOOL_NAME(EVP_des_ede3_wrap); +extern int GET_BOOL_NAME(EVP_des_ede_cbc); +extern int GET_BOOL_NAME(EVP_des_ede_cfb); +extern int GET_BOOL_NAME(EVP_des_ede_ecb); +extern int GET_BOOL_NAME(EVP_des_ede_ofb); +extern int GET_BOOL_NAME(EVP_des_ofb); +extern int GET_BOOL_NAME(EVP_md5); +extern int GET_BOOL_NAME(EVP_rc2_cbc); +extern int GET_BOOL_NAME(EVP_rc2_cfb); +extern int GET_BOOL_NAME(EVP_rc2_ecb); +extern int GET_BOOL_NAME(EVP_rc2_ofb); +extern int GET_BOOL_NAME(EVP_rc4); +extern int GET_BOOL_NAME(EVP_sha1); +extern int GET_BOOL_NAME(EVP_sha224); +extern int GET_BOOL_NAME(EVP_sha256); +extern int GET_BOOL_NAME(EVP_sha384); +extern int GET_BOOL_NAME(EVP_sha512); +extern int GET_BOOL_NAME(OPENSSL_malloc); +extern int GET_BOOL_NAME(OPENSSL_realloc); +extern int GET_BOOL_NAME(PEM_read_bio_PUBKEY); +extern int GET_BOOL_NAME(PEM_read_bio_Parameters); +extern int GET_BOOL_NAME(PEM_read_bio_PrivateKey); +extern int GET_BOOL_NAME(PEM_read_bio_X509); +extern int GET_BOOL_NAME(PEM_write_bio_PKCS8PrivateKey); +extern int GET_BOOL_NAME(PEM_write_bio_PUBKEY); +extern int GET_BOOL_NAME(PEM_write_bio_Parameters); +extern int GET_BOOL_NAME(PEM_write_bio_PrivateKey); +extern int GET_BOOL_NAME(PKCS5_PBKDF2_HMAC); +extern int GET_BOOL_NAME(RAND_bytes); +extern int GET_BOOL_NAME(RSA_private_decrypt); +extern int GET_BOOL_NAME(RSA_private_encrypt); +extern int GET_BOOL_NAME(RSA_public_decrypt); +extern int GET_BOOL_NAME(RSA_public_encrypt); +extern int GET_BOOL_NAME(X509_get_pubkey); +extern int GET_BOOL_NAME(d2i_DHparams_bio); +extern int GET_BOOL_NAME(d2i_DSAparams_bio); +extern int GET_BOOL_NAME(d2i_ECPKParameters_bio); +extern int GET_BOOL_NAME(d2i_PKCS8PrivateKey_bio); +extern int GET_BOOL_NAME(d2i_PUBKEY_bio); +extern int GET_BOOL_NAME(d2i_PrivateKey_bio); +extern int GET_BOOL_NAME(d2i_X509_bio); +extern int GET_BOOL_NAME(i2d_DHparams_bio); +extern int GET_BOOL_NAME(i2d_DSAparams_bio); +extern int GET_BOOL_NAME(i2d_ECPKParameters_bio); +extern int GET_BOOL_NAME(i2d_PKCS8PrivateKey_bio); +extern int GET_BOOL_NAME(i2d_PUBKEY_bio); +extern int GET_BOOL_NAME(i2d_PrivateKey_bio); + +#ifdef __cplusplus +} +#endif + +#endif // OPENSSL_MOCK_IMPL_H diff --git a/tests/openssl_mock_redefine.h b/tests/openssl_mock_redefine.h new file mode 100644 index 0000000..06b5adc --- /dev/null +++ b/tests/openssl_mock_redefine.h @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Pawelczyk + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file openssl_mock_redefine.h + * @brief + */ + +/* This file is to be included in the source files that want to mockup + * OpenSSL and libc. After OpenSSL and libc headers. E.g. + +#include +#include + +#ifdef OPENSSL_MOCKUP +#include "../tests/openssl_mock_redefine.h" +#endif + +*/ + +#include "openssl_mock_functions.h" + +#define open(a, b) MOCK_open(a, b) +#define read(a, b, c) MOCK_read(a, b, c) +#undef BIO_flush +#define BIO_flush(a) MOCK_BIO_flush(a) +#undef BIO_get_mem_data +#define BIO_get_mem_data(a, b) MOCK_BIO_get_mem_data(a, (char **)b) +#define BIO_new(a) MOCK_BIO_new(a) +#define BIO_new_mem_buf(a, b) MOCK_BIO_new_mem_buf(a, b) +#define BIO_read(a, b, c) MOCK_BIO_read(a, b, c) +#undef BIO_reset +#define BIO_reset(a) MOCK_BIO_reset(a) +#define BIO_write(a, b, c) MOCK_BIO_write(a, b, c) +#define CMAC_CTX_new() MOCK_CMAC_CTX_new() +#define CMAC_Init(a, b, c, d, e) MOCK_CMAC_Init(a, b, c, d, e) +#define DES_random_key(a) MOCK_DES_random_key(a) +#define DH_KDF_X9_42(a, b, c, d, e, f, g, h) MOCK_DH_KDF_X9_42(a, b, c, d, e, f, g, h) +#define ECDH_KDF_X9_62(a, b, c, d, e, f, g) MOCK_ECDH_KDF_X9_62(a, b, c, d, e, f, g) +#define EC_GROUP_get_asn1_flag(a) MOCK_EC_GROUP_get_asn1_flag(a) +#define EC_GROUP_get_curve_name(a) MOCK_EC_GROUP_get_curve_name(a) +#define EC_KEY_new() MOCK_EC_KEY_new() +#define EC_KEY_set_group(a, b) MOCK_EC_KEY_set_group(a, b) +#define EVP_CIPHER_CTX_block_size(a) MOCK_EVP_CIPHER_CTX_block_size(a) +#undef EVP_CIPHER_CTX_cleanup +#define EVP_CIPHER_CTX_cleanup(a) MOCK_EVP_CIPHER_CTX_cleanup(a) +#define EVP_CIPHER_CTX_ctrl(a, b, c, d) MOCK_EVP_CIPHER_CTX_ctrl(a, b, c, d) +#define EVP_CIPHER_CTX_new() MOCK_EVP_CIPHER_CTX_new() +#define EVP_CIPHER_CTX_set_key_length(a, b) MOCK_EVP_CIPHER_CTX_set_key_length(a, b) +#define EVP_CIPHER_CTX_set_padding(a, b) MOCK_EVP_CIPHER_CTX_set_padding(a, b) +#define EVP_CIPHER_iv_length(a) MOCK_EVP_CIPHER_iv_length(a) +#define EVP_CipherFinal(a, b, c) MOCK_EVP_CipherFinal(a, b, c) +#define EVP_CipherInit_ex(a, b, c, d, e, f) MOCK_EVP_CipherInit_ex(a, b, c, d, e, f) +#define EVP_CipherUpdate(a, b, c, d, e) MOCK_EVP_CipherUpdate(a, b, c, d, e) +#define EVP_DigestFinal_ex(a, b, c) MOCK_EVP_DigestFinal_ex(a, b, c) +#define EVP_DigestInit(a, b) MOCK_EVP_DigestInit(a, b) +#define EVP_DigestSignFinal(a, b, c) MOCK_EVP_DigestSignFinal(a, b, c) +#define EVP_DigestSignInit(a, b, c, d, e) MOCK_EVP_DigestSignInit(a, b, c, d, e) +#undef EVP_DigestSignUpdate +#define EVP_DigestSignUpdate(a, b, c) MOCK_EVP_DigestSignUpdate(a, b, c) +#undef EVP_DigestUpdate +#define EVP_DigestUpdate(a, b, c) MOCK_EVP_DigestUpdate(a, b, c) +#define EVP_DigestVerifyFinal(a, b, c) MOCK_EVP_DigestVerifyFinal(a, b, c) +#define EVP_DigestVerifyInit(a, b, c, d, e) MOCK_EVP_DigestVerifyInit(a, b, c, d, e) +#undef EVP_DigestVerifyUpdate +#define EVP_DigestVerifyUpdate(a, b, c) MOCK_EVP_DigestVerifyUpdate(a, b, c) +#undef EVP_MD_CTX_create +#define EVP_MD_CTX_create() MOCK_EVP_MD_CTX_create() +#define EVP_MD_CTX_pkey_ctx(a) MOCK_EVP_MD_CTX_pkey_ctx(a) +#undef EVP_MD_CTX_size +#define EVP_MD_CTX_size(a) MOCK_EVP_MD_CTX_size(a) +#define EVP_PKEY_CTX_ctrl(a, b, c, d, e, f) MOCK_EVP_PKEY_CTX_ctrl(a, b, c, d, e, f) +#define EVP_PKEY_CTX_get0_pkey(a) MOCK_EVP_PKEY_CTX_get0_pkey(a) +#define EVP_PKEY_CTX_new(a, b) MOCK_EVP_PKEY_CTX_new(a, b) +#define EVP_PKEY_CTX_new_id(a, b) MOCK_EVP_PKEY_CTX_new_id(a, b) +#undef EVP_PKEY_CTX_set_dh_paramgen_generator +#define EVP_PKEY_CTX_set_dh_paramgen_generator(a, b) MOCK_EVP_PKEY_CTX_set_dh_paramgen_generator(a, b) +#undef EVP_PKEY_CTX_set_dh_paramgen_prime_len +#define EVP_PKEY_CTX_set_dh_paramgen_prime_len(a, b) MOCK_EVP_PKEY_CTX_set_dh_paramgen_prime_len(a, b) +#undef EVP_PKEY_CTX_set_dsa_paramgen_bits +#define EVP_PKEY_CTX_set_dsa_paramgen_bits(a, b) MOCK_EVP_PKEY_CTX_set_dsa_paramgen_bits(a, b) +#undef EVP_PKEY_CTX_set_ec_param_enc +#define EVP_PKEY_CTX_set_ec_param_enc(a, b) MOCK_EVP_PKEY_CTX_set_ec_param_enc(a, b) +#undef EVP_PKEY_CTX_set_ec_paramgen_curve_nid +#define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(a, b) MOCK_EVP_PKEY_CTX_set_ec_paramgen_curve_nid(a, b) +#undef EVP_PKEY_CTX_set_rsa_keygen_bits +#define EVP_PKEY_CTX_set_rsa_keygen_bits(a, b) MOCK_EVP_PKEY_CTX_set_rsa_keygen_bits(a, b) +#undef EVP_PKEY_CTX_set_rsa_padding +#define EVP_PKEY_CTX_set_rsa_padding(a, b) MOCK_EVP_PKEY_CTX_set_rsa_padding(a, b) +#define EVP_PKEY_assign(a, b, c) MOCK_EVP_PKEY_assign(a, b, c) +#undef EVP_PKEY_assign_DH +#define EVP_PKEY_assign_DH(a, b) MOCK_EVP_PKEY_assign_DH(a, b) +#undef EVP_PKEY_assign_DSA +#define EVP_PKEY_assign_DSA(a, b) MOCK_EVP_PKEY_assign_DSA(a, b) +#undef EVP_PKEY_assign_EC_KEY +#define EVP_PKEY_assign_EC_KEY(a, b) MOCK_EVP_PKEY_assign_EC_KEY(a, b) +#define EVP_PKEY_bits(a) MOCK_EVP_PKEY_bits(a) +#define EVP_PKEY_decrypt_old(a, b, c, d) MOCK_EVP_PKEY_decrypt_old(a, b, c, d) +#define EVP_PKEY_derive(a, b, c) MOCK_EVP_PKEY_derive(a, b, c) +#define EVP_PKEY_derive_init(a) MOCK_EVP_PKEY_derive_init(a) +#define EVP_PKEY_derive_set_peer(a, b) MOCK_EVP_PKEY_derive_set_peer(a, b) +#define EVP_PKEY_encrypt_old(a, b, c, d) MOCK_EVP_PKEY_encrypt_old(a, b, c, d) +#define EVP_PKEY_keygen(a, b) MOCK_EVP_PKEY_keygen(a, b) +#define EVP_PKEY_keygen_init(a) MOCK_EVP_PKEY_keygen_init(a) +#define EVP_PKEY_new() MOCK_EVP_PKEY_new() +#define EVP_PKEY_new_mac_key(a, b, c, d) MOCK_EVP_PKEY_new_mac_key(a, b, c, d) +#define EVP_PKEY_paramgen(a, b) MOCK_EVP_PKEY_paramgen(a, b) +#define EVP_PKEY_paramgen_init(a) MOCK_EVP_PKEY_paramgen_init(a) +#define EVP_PKEY_size(a) MOCK_EVP_PKEY_size(a) +#define EVP_PKEY_up_ref(a) MOCK_EVP_PKEY_up_ref(a) +/* Special cases for algorithms, used as function pointers in YACA */ +#define EVP_aes_128_cbc MOCK_EVP_aes_128_cbc +#define EVP_aes_128_ccm MOCK_EVP_aes_128_ccm +#undef EVP_aes_128_cfb +#define EVP_aes_128_cfb MOCK_EVP_aes_128_cfb +#define EVP_aes_128_cfb1 MOCK_EVP_aes_128_cfb1 +#define EVP_aes_128_cfb8 MOCK_EVP_aes_128_cfb8 +#define EVP_aes_128_ctr MOCK_EVP_aes_128_ctr +#define EVP_aes_128_ecb MOCK_EVP_aes_128_ecb +#define EVP_aes_128_gcm MOCK_EVP_aes_128_gcm +#define EVP_aes_128_ofb MOCK_EVP_aes_128_ofb +#define EVP_aes_128_wrap MOCK_EVP_aes_128_wrap +#define EVP_aes_192_cbc MOCK_EVP_aes_192_cbc +#define EVP_aes_192_ccm MOCK_EVP_aes_192_ccm +#undef EVP_aes_192_cfb +#define EVP_aes_192_cfb MOCK_EVP_aes_192_cfb +#define EVP_aes_192_cfb1 MOCK_EVP_aes_192_cfb1 +#define EVP_aes_192_cfb8 MOCK_EVP_aes_192_cfb8 +#define EVP_aes_192_ctr MOCK_EVP_aes_192_ctr +#define EVP_aes_192_ecb MOCK_EVP_aes_192_ecb +#define EVP_aes_192_gcm MOCK_EVP_aes_192_gcm +#define EVP_aes_192_ofb MOCK_EVP_aes_192_ofb +#define EVP_aes_192_wrap MOCK_EVP_aes_192_wrap +#define EVP_aes_256_cbc MOCK_EVP_aes_256_cbc +#define EVP_aes_256_ccm MOCK_EVP_aes_256_ccm +#undef EVP_aes_256_cfb +#define EVP_aes_256_cfb MOCK_EVP_aes_256_cfb +#define EVP_aes_256_cfb1 MOCK_EVP_aes_256_cfb1 +#define EVP_aes_256_cfb8 MOCK_EVP_aes_256_cfb8 +#define EVP_aes_256_ctr MOCK_EVP_aes_256_ctr +#define EVP_aes_256_ecb MOCK_EVP_aes_256_ecb +#define EVP_aes_256_gcm MOCK_EVP_aes_256_gcm +#define EVP_aes_256_ofb MOCK_EVP_aes_256_ofb +#define EVP_aes_256_wrap MOCK_EVP_aes_256_wrap +#define EVP_cast5_cbc MOCK_EVP_cast5_cbc +#undef EVP_cast5_cfb +#define EVP_cast5_cfb MOCK_EVP_cast5_cfb +#define EVP_cast5_ecb MOCK_EVP_cast5_ecb +#define EVP_cast5_ofb MOCK_EVP_cast5_ofb +#define EVP_des_cbc MOCK_EVP_des_cbc +#undef EVP_des_cfb +#define EVP_des_cfb MOCK_EVP_des_cfb +#define EVP_des_cfb1 MOCK_EVP_des_cfb1 +#define EVP_des_cfb8 MOCK_EVP_des_cfb8 +#define EVP_des_ecb MOCK_EVP_des_ecb +#define EVP_des_ede3_cbc MOCK_EVP_des_ede3_cbc +#undef EVP_des_ede3_cfb +#define EVP_des_ede3_cfb MOCK_EVP_des_ede3_cfb +#define EVP_des_ede3_cfb1 MOCK_EVP_des_ede3_cfb1 +#define EVP_des_ede3_cfb8 MOCK_EVP_des_ede3_cfb8 +#define EVP_des_ede3_ecb MOCK_EVP_des_ede3_ecb +#define EVP_des_ede3_ofb MOCK_EVP_des_ede3_ofb +#define EVP_des_ede3_wrap MOCK_EVP_des_ede3_wrap +#define EVP_des_ede_cbc MOCK_EVP_des_ede_cbc +#undef EVP_des_ede_cfb +#define EVP_des_ede_cfb MOCK_EVP_des_ede_cfb +#define EVP_des_ede_ecb MOCK_EVP_des_ede_ecb +#define EVP_des_ede_ofb MOCK_EVP_des_ede_ofb +#define EVP_des_ofb MOCK_EVP_des_ofb +#define EVP_md5 MOCK_EVP_md5 +#define EVP_rc2_cbc MOCK_EVP_rc2_cbc +#undef EVP_rc2_cfb +#define EVP_rc2_cfb MOCK_EVP_rc2_cfb +#define EVP_rc2_ecb MOCK_EVP_rc2_ecb +#define EVP_rc2_ofb MOCK_EVP_rc2_ofb +#define EVP_rc4 MOCK_EVP_rc4 +#define EVP_sha1 MOCK_EVP_sha1 +#define EVP_sha224 MOCK_EVP_sha224 +#define EVP_sha256 MOCK_EVP_sha256 +#define EVP_sha384 MOCK_EVP_sha384 +#define EVP_sha512 MOCK_EVP_sha512 +#undef OPENSSL_malloc +#define OPENSSL_malloc(a) MOCK_OPENSSL_malloc(a) +#undef OPENSSL_realloc +#define OPENSSL_realloc(a, b) MOCK_OPENSSL_realloc(a, b) +#define PEM_read_bio_PUBKEY(a, b, c, d) MOCK_PEM_read_bio_PUBKEY(a, b, c, d) +#define PEM_read_bio_Parameters(a, b) MOCK_PEM_read_bio_Parameters(a, b) +#define PEM_read_bio_PrivateKey(a, b, c, d) MOCK_PEM_read_bio_PrivateKey(a, b, c, d) +#define PEM_read_bio_X509(a, b, c, d) MOCK_PEM_read_bio_X509(a, b, c, d) +#define PEM_write_bio_PKCS8PrivateKey(a, b, c, d, e, f, g) MOCK_PEM_write_bio_PKCS8PrivateKey(a, b, c, d, e, f, g) +#define PEM_write_bio_PUBKEY(a, b) MOCK_PEM_write_bio_PUBKEY(a, b) +#define PEM_write_bio_Parameters(a, b) MOCK_PEM_write_bio_Parameters(a, b) +#define PEM_write_bio_PrivateKey(a, b, c, d, e, f, g) MOCK_PEM_write_bio_PrivateKey(a, b, c, d, e, f, g) +#define PKCS5_PBKDF2_HMAC(a, b, c, d, e, f, g, h) MOCK_PKCS5_PBKDF2_HMAC(a, b, c, d, e, f, g, h) +#define RAND_bytes(a, b) MOCK_RAND_bytes(a, b) +/* 4 Special cases, used as function pointers in YACA */ +#define RSA_private_decrypt MOCK_RSA_private_decrypt +#define RSA_private_encrypt MOCK_RSA_private_encrypt +#define RSA_public_decrypt MOCK_RSA_public_decrypt +#define RSA_public_encrypt MOCK_RSA_public_encrypt +#define X509_get_pubkey(a) MOCK_X509_get_pubkey(a) +#undef d2i_DHparams_bio +#define d2i_DHparams_bio(a, b) MOCK_d2i_DHparams_bio(a, b) +#undef d2i_DSAparams_bio +#define d2i_DSAparams_bio(a, b) MOCK_d2i_DSAparams_bio(a, b) +#undef d2i_ECPKParameters_bio +#define d2i_ECPKParameters_bio(a, b) MOCK_d2i_ECPKParameters_bio(a, b) +#define d2i_PKCS8PrivateKey_bio(a, b, c, d) MOCK_d2i_PKCS8PrivateKey_bio(a, b, c, d) +#define d2i_PUBKEY_bio(a, b) MOCK_d2i_PUBKEY_bio(a, b) +#define d2i_PrivateKey_bio(a, b) MOCK_d2i_PrivateKey_bio(a, b) +#define d2i_X509_bio(a, b) MOCK_d2i_X509_bio(a, b) +#undef i2d_DHparams_bio +#define i2d_DHparams_bio(a, b) MOCK_i2d_DHparams_bio(a, b) +#undef i2d_DSAparams_bio +#define i2d_DSAparams_bio(a, b) MOCK_i2d_DSAparams_bio(a, b) +#undef i2d_ECPKParameters_bio +#define i2d_ECPKParameters_bio(a, b) MOCK_i2d_ECPKParameters_bio(a, b) +#define i2d_PKCS8PrivateKey_bio(a, b, c, d, e, f, g) MOCK_i2d_PKCS8PrivateKey_bio(a, b, c, d, e, f, g) +#define i2d_PUBKEY_bio(a, b) MOCK_i2d_PUBKEY_bio(a, b) +#define i2d_PrivateKey_bio(a, b) MOCK_i2d_PrivateKey_bio(a, b) -- 2.7.4 From cd5ade8ce65240e9016e0d427f0ee2d6299cc6c3 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Wed, 6 May 2020 14:35:53 +0200 Subject: [PATCH 13/16] Unit and system tests for YACA using OpenSSL mockup Those tests use OpenSSL mockup to test behaviour of YACA when OpenSSL fails. This code covers remaining ~16% of YACA's code. Change-Id: I1c22097155dc37a56c397b024abbc04a1c60faba --- tests/CMakeLists.txt | 8 + tests/common.h | 48 ++++ tests/mock_test_crypto.cpp | 113 ++++++++ tests/mock_test_digest.cpp | 83 ++++++ tests/mock_test_encrypt.cpp | 684 ++++++++++++++++++++++++++++++++++++++++++++ tests/mock_test_key.cpp | 573 +++++++++++++++++++++++++++++++++++++ tests/mock_test_rsa.cpp | 133 +++++++++ tests/mock_test_seal.cpp | 558 ++++++++++++++++++++++++++++++++++++ tests/mock_test_sign.cpp | 242 ++++++++++++++++ tests/mock_test_simple.cpp | 251 ++++++++++++++++ 10 files changed, 2693 insertions(+) create mode 100644 tests/mock_test_crypto.cpp create mode 100644 tests/mock_test_digest.cpp create mode 100644 tests/mock_test_encrypt.cpp create mode 100644 tests/mock_test_key.cpp create mode 100644 tests/mock_test_rsa.cpp create mode 100644 tests/mock_test_seal.cpp create mode 100644 tests/mock_test_sign.cpp create mode 100644 tests/mock_test_simple.cpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ad3eb0d..8e81541 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -34,6 +34,14 @@ SET(TESTS_SOURCES test_seal.cpp test_sign.cpp openssl_mock_impl.c + mock_test_crypto.cpp + mock_test_key.cpp + mock_test_simple.cpp + mock_test_rsa.cpp + mock_test_digest.cpp + mock_test_encrypt.cpp + mock_test_seal.cpp + mock_test_sign.cpp ) FIND_PACKAGE(Boost REQUIRED unit_test_framework) diff --git a/tests/common.h b/tests/common.h index 6c661e3..38d5122 100644 --- a/tests/common.h +++ b/tests/common.h @@ -31,6 +31,12 @@ #include #include "../src/debug.h" +#include "openssl_mock_impl.h" + +#include +#include +#include "../src/debug.h" + constexpr size_t INPUT_DATA_SIZE = 4096; constexpr char INPUT_DATA[INPUT_DATA_SIZE] = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus congue semper ipsum, ac convallis magna rhoncus sit amet. Donec pellentesque maximus convallis. Mauris ut egestas sem. Maecenas efficitur suscipit auctor. Nunc malesuada laoreet porttitor. Donec gravida tortor nisi, in mattis lectus porta ut. Integer vehicula eros et tellus placerat, nec fermentum justo aliquet.\ @@ -89,4 +95,46 @@ void call_update_loop(yaca_context_h ctx, const char *input, size_t input_len, char *output, size_t &output_len, size_t split, update_fun_5_t *fun); +/* This function automates using mockup infrastructure with the + * designated test (passed in the argument). The test is called in a + * loop starting with MOCK_fail_nth == 1 increasing it by 1 on every + * call. The idea is to fail all mocked up OpenSSL functions that the + * test uses one by one. In such cases the test is expected to fail. + * + * When the value of MOCK_fail_nth surpasses the number of used + * OpenSSL functions that are mocked up the test is expected to + * succeed and the function quits with a success. + * + * Every other outcome is considered a failure. + * + * See HANDLE_FUNCTION() in openssl_mock_impl.c + */ +template +void call_mock_test(func F) +{ + for (int n = 1; ; ++n) { + MOCK_fail_nth = n; + + int ret = F(); + + if (MOCK_fail_nth == 0) { + /* The nth OpenSSL function failed. The test is expected + * to fail. Increase the value and carry on. + */ + BOOST_REQUIRE_MESSAGE(ret != YACA_ERROR_NONE, + "The code should've failed\n"); + } else /* if (MOCK_fail_nth > 0) */ { + /* The n seems to be higher than the number of mocked up + * OpenSSL calls. The test is expected to succeed as no + * OpenSSL functions failed in the end. Quit the loop. + */ + BOOST_REQUIRE_MESSAGE(ret == YACA_ERROR_NONE, + "The code should've succeeded\n"); + MOCK_fail_nth = 0; + break; + } + } +} + + #endif /* COMMON_H */ diff --git a/tests/mock_test_crypto.cpp b/tests/mock_test_crypto.cpp new file mode 100644 index 0000000..93deb81 --- /dev/null +++ b/tests/mock_test_crypto.cpp @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Pawelczyk + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file mock_test_crypto.cpp + * @author Lukasz Pawelczyk + * @brief Base crypto API unit tests using mockup. + */ + +#include + +#include +#include + +#include +#include + +#include "common.h" +#include "openssl_mock_impl.h" + + +namespace { + +const size_t DATA_SIZE = 10; + +} + +BOOST_AUTO_TEST_SUITE(MOCK_TESTS_CRYPTO) + +BOOST_FIXTURE_TEST_CASE(T1101__mock__negative__malloc, InitFixture) +{ + int ret; + char *alloc; + + MOCK_fail_OPENSSL_malloc = 1; + ret = yaca_malloc(DATA_SIZE, (void**)&alloc); + BOOST_REQUIRE(ret == YACA_ERROR_OUT_OF_MEMORY); +} + + +BOOST_FIXTURE_TEST_CASE(T1102__mock__negative__zalloc, InitFixture) +{ + int ret; + char *alloc; + + MOCK_fail_OPENSSL_malloc = 1; + ret = yaca_zalloc(DATA_SIZE, (void**)&alloc); + BOOST_REQUIRE(ret == YACA_ERROR_OUT_OF_MEMORY); +} + + +BOOST_FIXTURE_TEST_CASE(T1103__mock__negative__realloc, InitFixture) +{ + int ret; + char *alloc; + + ret = yaca_zalloc(DATA_SIZE, (void**)&alloc); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + MOCK_fail_OPENSSL_realloc = 1; + ret = yaca_realloc(DATA_SIZE * 2, (void**)&alloc); + BOOST_REQUIRE(ret == YACA_ERROR_OUT_OF_MEMORY); + + yaca_free(alloc); +} + +BOOST_FIXTURE_TEST_CASE(T1104__mock__negative__randomize_bytes, InitFixture) +{ + int ret; + char buf[DATA_SIZE] = {}; + + MOCK_fail_RAND_bytes = 1; + ret = yaca_randomize_bytes(buf, DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_INTERNAL); +} + +#ifndef SYS_getrandom +BOOST_AUTO_TEST_CASE(T1105__mock__negative__sys_init) +{ + int ret; + + MOCK_fail_open = 1; + ret = yaca_initialize(); + BOOST_REQUIRE(ret == YACA_ERROR_INTERNAL); +} + +BOOST_FIXTURE_TEST_CASE(T1106__mock__negative__sys_randomize_bytes, InitFixture) +{ + int ret; + char data[DATA_SIZE]; + + MOCK_fail_read = 1; + ret = yaca_randomize_bytes(data, DATA_SIZE); + BOOST_REQUIRE(ret == YACA_ERROR_INTERNAL); +} +#endif + +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/mock_test_digest.cpp b/tests/mock_test_digest.cpp new file mode 100644 index 0000000..24ba81f --- /dev/null +++ b/tests/mock_test_digest.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Pawelczyk + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file test_digest.cpp + * @author Lukasz Pawelczyk + * @brief Digest API unit tests. + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "common.h" + + +BOOST_AUTO_TEST_SUITE(MOCK_TESTS_DIGEST) + +BOOST_FIXTURE_TEST_CASE(T1501__mock__negative__yaca_digest, InitFixture) +{ + struct digest_args { + yaca_digest_algorithm_e algo = YACA_DIGEST_SHA256; + }; + + const std::vector dargs = { + {yaca_digest_algorithm_e::YACA_DIGEST_MD5}, + {yaca_digest_algorithm_e::YACA_DIGEST_SHA224} + }; + + for (const auto &da: dargs) { + auto test_code = [&da]() -> int + { + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + char *digest = NULL; + size_t digest_len; + + ret = yaca_digest_initialize(&ctx, da.algo); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_digest_update(ctx, INPUT_DATA, INPUT_DATA_SIZE); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_get_output_length(ctx, 0, &digest_len); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_malloc(digest_len, (void**)&digest); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_digest_finalize(ctx, digest, &digest_len); + if (ret != YACA_ERROR_NONE) goto exit; + + exit: + yaca_context_destroy(ctx); + yaca_free(digest); + return ret; + }; + + call_mock_test(test_code); + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/mock_test_encrypt.cpp b/tests/mock_test_encrypt.cpp new file mode 100644 index 0000000..e2657b5 --- /dev/null +++ b/tests/mock_test_encrypt.cpp @@ -0,0 +1,684 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Pawelczyk + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file test_encrypt.cpp + * @author Lukasz Pawelczyk + * @brief Encrypt API unit tests. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "common.h" + + +BOOST_AUTO_TEST_SUITE(MOCK_TESTS_ENCRYPT) + +BOOST_FIXTURE_TEST_CASE(T1601__mock__negative__encrypt_decrypt, InitFixture) +{ + struct encrypt_args { + yaca_encrypt_algorithm_e algo; + yaca_block_cipher_mode_e bcm; + size_t key_bit_len; + yaca_padding_e padding; + }; + + const std::vector eargs = { + {YACA_ENCRYPT_AES, YACA_BCM_CBC, 128, YACA_PADDING_NONE }, + {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_OFB, 64, YACA_INVALID_PADDING}, + {YACA_ENCRYPT_UNSAFE_3DES_2TDEA, YACA_BCM_CBC, 128, YACA_PADDING_PKCS7 }, + {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_CFB1, 192, YACA_INVALID_PADDING}, + {YACA_ENCRYPT_UNSAFE_RC4, YACA_BCM_NONE, 256, YACA_INVALID_PADDING}, + {YACA_ENCRYPT_CAST5, YACA_BCM_ECB, 128, YACA_PADDING_NONE } + }; + + for (const auto &ea: eargs) { + auto test_code = [&ea]() + { + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key = YACA_KEY_NULL, iv = YACA_KEY_NULL; + + size_t iv_bit_len, len1 = 0, len2 = 0; + + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len = 0, decrypted_len = 0; + + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, ea.key_bit_len, &key); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_encrypt_get_iv_bit_length(ea.algo, ea.bcm, ea.key_bit_len, &iv_bit_len); + if (ret != YACA_ERROR_NONE) goto exit; + + if (iv_bit_len > 0) { + ret = yaca_key_generate(YACA_KEY_TYPE_IV, iv_bit_len, &iv); + if (ret != YACA_ERROR_NONE) goto exit; + } + + /* ENCRYPT */ + { + ret = yaca_encrypt_initialize(&ctx, ea.algo, ea.bcm, key, iv); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_get_output_length(ctx, INPUT_DATA_SIZE, &len1); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_context_get_output_length(ctx, 0, &len2); + if (ret != YACA_ERROR_NONE) goto exit; + + size_t total = len1 + len2; + size_t written; + + ret = yaca_zalloc(total, (void**)&encrypted); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_encrypt_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + if (ret != YACA_ERROR_NONE) goto exit; + encrypted_len = written; + + if (ea.padding != YACA_INVALID_PADDING) { + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, &ea.padding, + sizeof(yaca_padding_e)); + if (ret != YACA_ERROR_NONE) goto exit; + } + + ret = yaca_encrypt_finalize(ctx, encrypted + encrypted_len, &written); + if (ret != YACA_ERROR_NONE) goto exit; + encrypted_len += written; + + ret = yaca_realloc(encrypted_len, (void **)&encrypted); + if (ret != YACA_ERROR_NONE) goto exit; + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* DECRYPT */ + { + ret = yaca_decrypt_initialize(&ctx, ea.algo, ea.bcm, key, iv); + if (ret != YACA_ERROR_NONE) goto exit; + + if (ea.padding != YACA_INVALID_PADDING) { + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, &ea.padding, + sizeof(yaca_padding_e)); + if (ret != YACA_ERROR_NONE) goto exit; + } + + ret = yaca_context_get_output_length(ctx, encrypted_len, &len1); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_context_get_output_length(ctx, 0, &len2); + if (ret != YACA_ERROR_NONE) goto exit; + + size_t total = len1 + len2; + size_t written; + + ret = yaca_zalloc(total, (void**)&decrypted); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + if (ret != YACA_ERROR_NONE) goto exit; + decrypted_len = written; + + ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); + if (ret != YACA_ERROR_NONE) goto exit; + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + exit: + yaca_context_destroy(ctx); + yaca_key_destroy(key); + yaca_key_destroy(iv); + yaca_free(encrypted); + yaca_free(decrypted); + return ret; + }; + + call_mock_test(test_code); + } +} + +BOOST_FIXTURE_TEST_CASE(T1602__mock__negative__encrypt_decrypt_wrap, InitFixture) +{ + struct encrypt_args { + yaca_encrypt_algorithm_e algo; + size_t key_bit_len; + size_t key_material_len; + }; + + const std::vector eargs = { + {YACA_ENCRYPT_AES, 128, 192 / 8}, + {YACA_ENCRYPT_3DES_3TDEA, 192, 128 / 8}, + }; + + for (const auto &ea: eargs) { + auto test_code = [&ea]() + { + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key = YACA_KEY_NULL, iv = YACA_KEY_NULL; + char *key_material = NULL; + + size_t iv_bit_len, len1, len2; + + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len, decrypted_len; + + ret = yaca_zalloc(ea.key_material_len, (void**)&key_material); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_randomize_bytes(key_material, ea.key_material_len); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, ea.key_bit_len, &key); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_encrypt_get_iv_bit_length(ea.algo, YACA_BCM_WRAP, ea.key_bit_len, &iv_bit_len); + if (ret != YACA_ERROR_NONE) goto exit; + + if (iv_bit_len > 0) { + ret = yaca_key_generate(YACA_KEY_TYPE_IV, iv_bit_len, &iv); + if (ret != YACA_ERROR_NONE) goto exit; + } + + /* ENCRYPT */ + { + ret = yaca_encrypt_initialize(&ctx, ea.algo, YACA_BCM_WRAP, key, iv); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_get_output_length(ctx, ea.key_material_len, &len1); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_context_get_output_length(ctx, 0, &len2); + if (ret != YACA_ERROR_NONE) goto exit; + + size_t total = len1 + len2; + size_t written; + + ret = yaca_zalloc(total, (void**)&encrypted); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_encrypt_update(ctx, key_material, ea.key_material_len, + encrypted, &written); + if (ret != YACA_ERROR_NONE) goto exit; + encrypted_len = written; + + ret = yaca_encrypt_finalize(ctx, encrypted + encrypted_len, &written); + if (ret != YACA_ERROR_NONE) goto exit; + encrypted_len += written; + + ret = yaca_realloc(encrypted_len, (void **)&encrypted); + if (ret != YACA_ERROR_NONE) goto exit; + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* DECRYPT */ + { + ret = yaca_decrypt_initialize(&ctx, ea.algo, YACA_BCM_WRAP, key, iv); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_get_output_length(ctx, encrypted_len, &len1); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_context_get_output_length(ctx, 0, &len2); + if (ret != YACA_ERROR_NONE) goto exit; + + size_t total = len1 + len2; + size_t written; + + ret = yaca_zalloc(total, (void**)&decrypted); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + if (ret != YACA_ERROR_NONE) goto exit; + decrypted_len = written; + + ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); + if (ret != YACA_ERROR_NONE) goto exit; + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + exit: + yaca_context_destroy(ctx); + yaca_key_destroy(key); + yaca_key_destroy(iv); + yaca_free(key_material); + yaca_free(encrypted); + yaca_free(decrypted); + return ret; + }; + + call_mock_test(test_code); + } +} + +BOOST_FIXTURE_TEST_CASE(T1603__mock__negative__encrypt_decrypt_rc2, InitFixture) +{ + struct encrypt_args { + yaca_block_cipher_mode_e bcm; + size_t key_bit_len; + yaca_padding_e padding; + size_t effective_key_bits; + }; + + const std::vector eargs = { + {YACA_BCM_CBC, 224, YACA_INVALID_PADDING, 1}, + {YACA_BCM_CBC, 192, YACA_PADDING_NONE, 64}, + {YACA_BCM_CBC, 272, YACA_PADDING_PKCS7, 8}, + }; + + for (const auto &ea: eargs) { + auto test_code = [&ea]() + { + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key = YACA_KEY_NULL, iv = YACA_KEY_NULL; + + size_t iv_bit_len, len1 = 0, len2 = 0; + + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len = 0, decrypted_len = 0; + + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, ea.key_bit_len, &key); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_encrypt_get_iv_bit_length(YACA_ENCRYPT_UNSAFE_RC2, ea.bcm, ea.key_bit_len, &iv_bit_len); + if (ret != YACA_ERROR_NONE) goto exit; + + if (iv_bit_len > 0) { + ret = yaca_key_generate(YACA_KEY_TYPE_IV, iv_bit_len, &iv); + if (ret != YACA_ERROR_NONE) goto exit; + } + + /* ENCRYPT */ + { + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_UNSAFE_RC2, ea.bcm, key, iv); + if (ret != YACA_ERROR_NONE) goto exit; + + if (ea.padding != YACA_INVALID_PADDING) { + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &ea.padding, sizeof(yaca_padding_e)); + if (ret != YACA_ERROR_NONE) goto exit; + } + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_RC2_EFFECTIVE_KEY_BITS, + &ea.effective_key_bits, sizeof(size_t)); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_get_output_length(ctx, INPUT_DATA_SIZE, &len1); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_context_get_output_length(ctx, 0, &len2); + if (ret != YACA_ERROR_NONE) goto exit; + + size_t total = len1 + len2; + size_t written; + + ret = yaca_zalloc(total, (void**)&encrypted); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_encrypt_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + if (ret != YACA_ERROR_NONE) goto exit; + encrypted_len = written; + + ret = yaca_encrypt_finalize(ctx, encrypted + encrypted_len, &written); + if (ret != YACA_ERROR_NONE) goto exit; + encrypted_len += written; + + ret = yaca_realloc(encrypted_len, (void **)&encrypted); + if (ret != YACA_ERROR_NONE) goto exit; + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* DECRYPT */ + { + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_UNSAFE_RC2, ea.bcm, key, iv); + if (ret != YACA_ERROR_NONE) goto exit; + + if (ea.padding != YACA_INVALID_PADDING) { + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &ea.padding, sizeof(yaca_padding_e)); + if (ret != YACA_ERROR_NONE) goto exit; + } + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_RC2_EFFECTIVE_KEY_BITS, + &ea.effective_key_bits, sizeof(size_t)); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_get_output_length(ctx, encrypted_len, &len1); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_context_get_output_length(ctx, 0, &len2); + if (ret != YACA_ERROR_NONE) goto exit; + + size_t total = len1 + len2; + size_t written; + + ret = yaca_zalloc(total, (void**)&decrypted); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + if (ret != YACA_ERROR_NONE) goto exit; + decrypted_len = written; + + ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); + if (ret != YACA_ERROR_NONE) goto exit; + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + exit: + yaca_context_destroy(ctx); + yaca_key_destroy(key); + yaca_key_destroy(iv); + yaca_free(encrypted); + yaca_free(decrypted); + return ret; + }; + + call_mock_test(test_code); + } +} + +BOOST_FIXTURE_TEST_CASE(T1604__mock__negative__encrypt_decrypt_ccm, InitFixture) +{ + struct encrypt_args { + size_t key_bit_len; + size_t ccm_tag_len; + size_t aad_len; + size_t iv_bit_len; + }; + + const std::vector eargs = { + {128, 12, 19, 64}, + {192, 10, 34, 96} + }; + + for (const auto &ea: eargs) { + auto test_code = [&ea]() + { + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key = YACA_KEY_NULL, iv = YACA_KEY_NULL; + + size_t len1, len2; + + char *tag = NULL, *aad = NULL; + size_t tag_len; + + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len, decrypted_len; + + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, ea.key_bit_len, &key); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_key_generate(YACA_KEY_TYPE_IV, ea.iv_bit_len, &iv); + if (ret != YACA_ERROR_NONE) goto exit; + + /* ENCRYPT */ + { + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CCM, key, iv); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_get_output_length(ctx, INPUT_DATA_SIZE, &len1); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_context_get_output_length(ctx, 0, &len2); + if (ret != YACA_ERROR_NONE) goto exit; + + size_t total = len1 + len2; + size_t written; + + ret = yaca_zalloc(total, (void**)&encrypted); + if (ret != YACA_ERROR_NONE) goto exit; + + tag_len = ea.ccm_tag_len; + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG_LEN, + &tag_len, sizeof(tag_len)); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_malloc(ea.aad_len, (void**)&aad); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_randomize_bytes(aad, ea.aad_len); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_encrypt_update(ctx, NULL, INPUT_DATA_SIZE, + NULL, &written); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, + aad, ea.aad_len); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_encrypt_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + if (ret != YACA_ERROR_NONE) goto exit; + encrypted_len = written; + + ret = yaca_encrypt_finalize(ctx, encrypted + encrypted_len, &written); + if (ret != YACA_ERROR_NONE) goto exit; + encrypted_len += written; + + ret = yaca_realloc(encrypted_len, (void **)&encrypted); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_get_property(ctx, YACA_PROPERTY_CCM_TAG, (void**)&tag, &tag_len); + if (ret != YACA_ERROR_NONE) goto exit; + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* DECRYPT */ + { + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CCM, key, iv); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_get_output_length(ctx, encrypted_len, &len1); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_context_get_output_length(ctx, 0, &len2); + if (ret != YACA_ERROR_NONE) goto exit; + + size_t total = len1 + len2; + size_t written; + + ret = yaca_zalloc(total, (void**)&decrypted); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG, tag, tag_len); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_decrypt_update(ctx, NULL, encrypted_len, + NULL, &written); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, + aad, ea.aad_len); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + if (ret != YACA_ERROR_NONE) goto exit; + decrypted_len = written; + + ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); + if (ret != YACA_ERROR_NONE) goto exit; + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + exit: + yaca_context_destroy(ctx); + yaca_key_destroy(key); + yaca_key_destroy(iv); + yaca_free(encrypted); + yaca_free(decrypted); + yaca_free(tag); + yaca_free(aad); + return ret; + }; + + call_mock_test(test_code); + } +} + +BOOST_FIXTURE_TEST_CASE(T1605__mock__negative__encrypt_decrypt_gcm, InitFixture) +{ + struct encrypt_args { + size_t key_bit_len; + size_t gcm_tag_len; + size_t aad_len; + size_t iv_bit_len; + }; + + const std::vector eargs = { + {128, 13, 22, 64}, + {256, 14, 12, 128} + }; + + for (const auto &ea: eargs) { + auto test_code = [&ea]() + { + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key = YACA_KEY_NULL, iv = YACA_KEY_NULL; + + size_t len1 = 0, len2 = 0; + + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len = 0, decrypted_len = 0; + + char *tag = NULL, *aad = NULL; + size_t tag_len; + + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, ea.key_bit_len, &key); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_key_generate(YACA_KEY_TYPE_IV, ea.iv_bit_len, &iv); + if (ret != YACA_ERROR_NONE) goto exit; + + /* ENCRYPT */ + { + ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_GCM, key, iv); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_get_output_length(ctx, INPUT_DATA_SIZE, &len1); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_context_get_output_length(ctx, 0, &len2); + if (ret != YACA_ERROR_NONE) goto exit; + + size_t total = len1 + len2; + size_t written; + + ret = yaca_zalloc(total, (void**)&encrypted); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_malloc(ea.aad_len, (void**)&aad); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_randomize_bytes(aad, ea.aad_len); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_AAD, + aad, ea.aad_len); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_encrypt_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + if (ret != YACA_ERROR_NONE) goto exit; + encrypted_len = written; + + ret = yaca_encrypt_finalize(ctx, encrypted + encrypted_len, &written); + if (ret != YACA_ERROR_NONE) goto exit; + encrypted_len += written; + + ret = yaca_realloc(encrypted_len, (void **)&encrypted); + if (ret != YACA_ERROR_NONE) goto exit; + + tag_len = ea.gcm_tag_len; + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_TAG_LEN, + &tag_len, sizeof(tag_len)); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_get_property(ctx, YACA_PROPERTY_GCM_TAG, + (void**)&tag, &tag_len); + if (ret != YACA_ERROR_NONE) goto exit; + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* DECRYPT */ + { + ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_GCM, key, iv); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_get_output_length(ctx, encrypted_len, &len1); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_context_get_output_length(ctx, 0, &len2); + if (ret != YACA_ERROR_NONE) goto exit; + + size_t total = len1 + len2; + size_t written; + + ret = yaca_zalloc(total, (void**)&decrypted); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_AAD, + aad, ea.aad_len); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); + if (ret != YACA_ERROR_NONE) goto exit; + decrypted_len = written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_TAG, + tag, tag_len); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); + if (ret != YACA_ERROR_NONE) goto exit; + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + exit: + yaca_context_destroy(ctx); + yaca_key_destroy(key); + yaca_key_destroy(iv); + yaca_free(encrypted); + yaca_free(decrypted); + yaca_free(tag); + yaca_free(aad); + return ret; + }; + + call_mock_test(test_code); + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/mock_test_key.cpp b/tests/mock_test_key.cpp new file mode 100644 index 0000000..2c94c4d --- /dev/null +++ b/tests/mock_test_key.cpp @@ -0,0 +1,573 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Pawelczyk + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file test_key.cpp + * @author Lukasz Pawelczyk + * @brief Key API unit tests. + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "common.h" + + +namespace { + +int import_export(yaca_key_h key, yaca_key_type_e type, const char *password, + yaca_key_format_e format, yaca_key_file_format_e file_format) +{ + int ret; + yaca_key_h imported = YACA_KEY_NULL; + + char *data = NULL; + size_t data_len = 0; + yaca_key_type_e key_type; + size_t key_length; + + ret = yaca_key_export(key, format, file_format, + password, &data, &data_len); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_key_import(type, password, data, data_len, &imported); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_key_get_type(imported, &key_type); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_key_get_bit_length(imported, &key_length); + if (ret != YACA_ERROR_NONE) goto exit; + +exit: + yaca_key_destroy(imported); + yaca_free(data); + return ret; +} + +} // namespace + + +BOOST_AUTO_TEST_SUITE(MOCK_TESTS_KEY) + +BOOST_FIXTURE_TEST_CASE(T1201__mock__negative__key_symmetric_all, InitFixture) +{ + struct key_args { + yaca_key_type_e type; + yaca_key_bit_length_e len; + }; + + const std::vector kargs = { + {YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_256BIT}, + {YACA_KEY_TYPE_DES, YACA_KEY_LENGTH_192BIT}, + {YACA_KEY_TYPE_IV, YACA_KEY_LENGTH_IV_64BIT} + }; + + for (const auto &ka: kargs) { + auto test_code = [&ka]() + { + int ret; + yaca_key_h key = YACA_KEY_NULL; + + ret = yaca_key_generate(ka.type, ka.len, &key); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = import_export(key, ka.type, "", + YACA_KEY_FORMAT_DEFAULT, + YACA_KEY_FILE_FORMAT_RAW); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = import_export(key, ka.type, "", + YACA_KEY_FORMAT_DEFAULT, + YACA_KEY_FILE_FORMAT_BASE64); + if (ret != YACA_ERROR_NONE) goto exit; + + exit: + yaca_key_destroy(key); + return ret; + }; + + call_mock_test(test_code); + } +} + +BOOST_FIXTURE_TEST_CASE(T1202__mock__negative__key_asymmetric_generate_all, InitFixture) +{ + struct key_args { + yaca_key_type_e type_priv; + yaca_key_type_e type_pub; + yaca_key_type_e type_params; + yaca_key_bit_length_e len; + }; + + const std::vector kargs = { + {YACA_KEY_TYPE_RSA_PRIV, + YACA_KEY_TYPE_RSA_PUB, + YACA_INVALID_KEY_TYPE, + YACA_KEY_LENGTH_512BIT}, + {YACA_KEY_TYPE_DSA_PRIV, + YACA_KEY_TYPE_DSA_PUB, + YACA_KEY_TYPE_DSA_PARAMS, + YACA_KEY_LENGTH_512BIT}, + {YACA_KEY_TYPE_DH_PRIV, + YACA_KEY_TYPE_DH_PUB, + YACA_KEY_TYPE_DH_PARAMS, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_DH_RFC_1024_160}, + {YACA_KEY_TYPE_EC_PRIV, + YACA_KEY_TYPE_EC_PUB, + YACA_KEY_TYPE_EC_PARAMS, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_EC_PRIME192V1} + }; + + for (const auto &ka: kargs) { + auto test_code = [&ka]() + { + int ret; + yaca_key_h priv = YACA_KEY_NULL; + yaca_key_h priv2 = YACA_KEY_NULL; + yaca_key_h pub = YACA_KEY_NULL; + yaca_key_h params = YACA_KEY_NULL; + yaca_key_h params2 = YACA_KEY_NULL; + + ret = yaca_key_generate(ka.type_priv, ka.len, &priv); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_key_extract_public(priv, &pub); + if (ret != YACA_ERROR_NONE) goto exit; + + if (ka.type_params != YACA_INVALID_KEY_TYPE) { + ret = yaca_key_generate(ka.type_params, ka.len, ¶ms); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_key_generate_from_parameters(params, &priv2); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_key_extract_parameters(pub, ¶ms2); + if (ret != YACA_ERROR_NONE) goto exit; + } + + exit: + yaca_key_destroy(params); + yaca_key_destroy(params2); + yaca_key_destroy(priv); + yaca_key_destroy(priv2); + yaca_key_destroy(pub); + return ret; + }; + + call_mock_test(test_code); + } +} + +BOOST_FIXTURE_TEST_CASE(T1204__mock__negative__key_asymmetric_import_export, InitFixture) +{ + struct key_args { + yaca_key_type_e type_priv; + yaca_key_type_e type_pub; + yaca_key_type_e type_params; + yaca_key_bit_length_e len; + }; + + const std::vector kargs = { + {YACA_KEY_TYPE_RSA_PRIV, + YACA_KEY_TYPE_RSA_PUB, + YACA_INVALID_KEY_TYPE, + YACA_KEY_LENGTH_512BIT}, + {YACA_KEY_TYPE_DSA_PRIV, + YACA_KEY_TYPE_DSA_PUB, + YACA_KEY_TYPE_DSA_PARAMS, + YACA_KEY_LENGTH_512BIT}, + {YACA_KEY_TYPE_EC_PRIV, + YACA_KEY_TYPE_EC_PUB, + YACA_KEY_TYPE_EC_PARAMS, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_EC_PRIME192V1}, + {YACA_KEY_TYPE_DH_PRIV, + YACA_KEY_TYPE_DH_PUB, + YACA_KEY_TYPE_DH_PARAMS, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_DH_RFC_1024_160}, + }; + + for (const auto &ka: kargs) { + auto test_code = [&ka]() + { + int ret; + yaca_key_h key_priv = YACA_KEY_NULL; + yaca_key_h key_pub = YACA_KEY_NULL; + yaca_key_h key_params = YACA_KEY_NULL; + + ret = yaca_key_generate(ka.type_priv, ka.len, &key_priv); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = import_export(key_priv, ka.type_priv, NULL, + YACA_KEY_FORMAT_DEFAULT, + YACA_KEY_FILE_FORMAT_DER); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = import_export(key_priv, ka.type_priv, NULL, + YACA_KEY_FORMAT_DEFAULT, + YACA_KEY_FILE_FORMAT_PEM); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_key_extract_public(key_priv, &key_pub); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = import_export(key_pub, ka.type_pub, "", + YACA_KEY_FORMAT_DEFAULT, + YACA_KEY_FILE_FORMAT_DER); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = import_export(key_pub, ka.type_pub, "", + YACA_KEY_FORMAT_DEFAULT, + YACA_KEY_FILE_FORMAT_PEM); + if (ret != YACA_ERROR_NONE) goto exit; + + if (ka.type_params != YACA_INVALID_KEY_TYPE) { + ret = yaca_key_extract_parameters(key_priv, &key_params); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = import_export(key_params, ka.type_params, NULL, + YACA_KEY_FORMAT_DEFAULT, + YACA_KEY_FILE_FORMAT_DER); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = import_export(key_params, ka.type_params, NULL, + YACA_KEY_FORMAT_DEFAULT, + YACA_KEY_FILE_FORMAT_PEM); + if (ret != YACA_ERROR_NONE) goto exit; + } + + exit: + yaca_key_destroy(key_params); + yaca_key_destroy(key_priv); + yaca_key_destroy(key_pub); + return ret; + }; + + call_mock_test(test_code); + } +} + +BOOST_FIXTURE_TEST_CASE(T1205__mock__negative__key_encrypted_import_export, InitFixture) +{ + static const char *PASSWORD = "ExamplE_PassworD"; + + struct default_args { + yaca_key_type_e type; + yaca_key_bit_length_e len; + }; + + const std::vector dargs = { + {YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_512BIT}, + {YACA_KEY_TYPE_DSA_PRIV, YACA_KEY_LENGTH_512BIT} + }; + + for (const auto &da: dargs) { + auto test_code = [&da]() + { + int ret; + yaca_key_h key = YACA_KEY_NULL; + + ret = yaca_key_generate(da.type, da.len, &key); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = import_export(key, da.type, PASSWORD, + YACA_KEY_FORMAT_DEFAULT, + YACA_KEY_FILE_FORMAT_PEM); + if (ret != YACA_ERROR_NONE) goto exit; + + exit: + yaca_key_destroy(key); + return ret; + }; + + call_mock_test(test_code); + } + + struct pkcs8_args { + yaca_key_type_e type; + yaca_key_bit_length_e len; + }; + + const std::vector pargs { + {YACA_KEY_TYPE_RSA_PRIV, + YACA_KEY_LENGTH_512BIT}, + {YACA_KEY_TYPE_DSA_PRIV, + YACA_KEY_LENGTH_512BIT}, + {YACA_KEY_TYPE_EC_PRIV, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_EC_PRIME256V1}, + {YACA_KEY_TYPE_DH_PRIV, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_DH_RFC_1024_160}, + }; + + for (const auto &pa: pargs) { + auto test_code2 = [&pa]() + { + int ret; + yaca_key_h key = YACA_KEY_NULL; + + ret = yaca_key_generate(pa.type, pa.len, &key); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = import_export(key, pa.type, PASSWORD, + YACA_KEY_FORMAT_PKCS8, + YACA_KEY_FILE_FORMAT_DER); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = import_export(key, pa.type, PASSWORD, + YACA_KEY_FORMAT_PKCS8, + YACA_KEY_FILE_FORMAT_PEM); + if (ret != YACA_ERROR_NONE) goto exit; + + exit: + yaca_key_destroy(key); + return ret; + }; + + call_mock_test(test_code2); + } +} + +BOOST_FIXTURE_TEST_CASE(T1206__mock__negative__key_derive_dh, InitFixture) +{ + struct key_args { + yaca_key_type_e type; + yaca_key_bit_length_e len; + }; + + const std::vector kargs = { + {YACA_KEY_TYPE_DH_PRIV, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_DH_RFC_1024_160}, + {YACA_KEY_TYPE_EC_PRIV, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_EC_SECP256K1} + }; + + for (const auto &ka: kargs) { + auto test_code = [&ka]() + { + int ret; + yaca_key_h priv1 = YACA_KEY_NULL, pub1 = YACA_KEY_NULL; + yaca_key_h priv2 = YACA_KEY_NULL, pub2 = YACA_KEY_NULL; + char *secret1 = NULL, *secret2 = NULL; + size_t secret1_len, secret2_len; + + ret = yaca_key_generate(ka.type, ka.len, &priv1); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_key_generate(ka.type, ka.len, &priv2); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_key_extract_public(priv1, &pub1); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_key_extract_public(priv2, &pub2); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_key_derive_dh(priv1, pub2, &secret1, &secret1_len); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_key_derive_dh(priv2, pub1, &secret2, &secret2_len); + if (ret != YACA_ERROR_NONE) goto exit; + + exit: + yaca_key_destroy(priv1); + yaca_key_destroy(priv2); + yaca_key_destroy(pub1); + yaca_key_destroy(pub2); + yaca_free(secret1); + yaca_free(secret2); + return ret; + }; + + call_mock_test(test_code); + } +} + +BOOST_FIXTURE_TEST_CASE(T1207__mock__negative__key_derive_kdf, InitFixture) +{ + static const size_t SECRET_LEN = 128; + static const size_t MATERIAL_LEN = 256; + + struct kdf_args { + yaca_kdf_e kdf; + yaca_digest_algorithm_e digest; + }; + + const std::vector kargs = { + {YACA_KDF_X942, YACA_DIGEST_SHA1}, + {YACA_KDF_X962, YACA_DIGEST_MD5} + }; + + int ret; + char secret[SECRET_LEN]; + + ret = yaca_randomize_bytes(secret, SECRET_LEN); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + for (const auto &ka: kargs) { + auto test_code = [&ka, &secret]() + { + int ret; + char *key_material = NULL;; + + ret = yaca_key_derive_kdf(ka.kdf, ka.digest, secret, SECRET_LEN, + NULL, 0, MATERIAL_LEN, &key_material); + + yaca_free(key_material); + return ret; + }; + + call_mock_test(test_code); + } +} + +BOOST_FIXTURE_TEST_CASE(T1208__mock__negative__key_derive_pbkdf2, InitFixture) +{ + static const char *PASSWORD = "Password_ExamplE"; + static const size_t SALT_LEN = 64; + + struct pbkdf2_args { + yaca_digest_algorithm_e digest; + size_t iter; + size_t bit_len; + }; + + const std::vector pargs = { + {YACA_DIGEST_MD5, 1, 256}, + {YACA_DIGEST_SHA512, 50, 512} + }; + + int ret; + char salt[SALT_LEN]; + + ret = yaca_randomize_bytes(salt, SALT_LEN); + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + + for (const auto &pa: pargs) { + auto test_code = [&pa, &salt]() + { + int ret; + yaca_key_h key = YACA_KEY_NULL; + + ret = yaca_key_derive_pbkdf2(PASSWORD, salt, SALT_LEN, pa.iter, + pa.digest, pa.bit_len, &key); + + yaca_key_destroy(key); + return ret; + }; + + call_mock_test(test_code); + } +} + +BOOST_FIXTURE_TEST_CASE(T1209__mock__negative__import_x509_cert, InitFixture) +{ + static const char data_pem[] = "-----BEGIN CERTIFICATE-----\n\ +MIIC9jCCAl+gAwIBAgIUaWM7DVy/evvsrKz8gkz3qWZKw7EwDQYJKoZIhvcNAQEL\n\ +BQAwgYwxCzAJBgNVBAYTAlBMMRQwEgYDVQQIDAtNYXpvd2llY2tpZTERMA8GA1UE\n\ +BwwIV2Fyc3phd2ExEDAOBgNVBAoMB1NhbXN1bmcxCzAJBgNVBAsMAklUMRQwEgYD\n\ +VQQDDAtzYW1zdW5nLmNvbTEfMB0GCSqGSIb3DQEJARYQbm9uZUBzYW1zdW5nLmNv\n\ +bTAeFw0yMDA0MDkxNzUzMDlaFw0yNTA0MDgxNzUzMDlaMIGMMQswCQYDVQQGEwJQ\n\ +TDEUMBIGA1UECAwLTWF6b3dpZWNraWUxETAPBgNVBAcMCFdhcnN6YXdhMRAwDgYD\n\ +VQQKDAdTYW1zdW5nMQswCQYDVQQLDAJJVDEUMBIGA1UEAwwLc2Ftc3VuZy5jb20x\n\ +HzAdBgkqhkiG9w0BCQEWEG5vbmVAc2Ftc3VuZy5jb20wgZ8wDQYJKoZIhvcNAQEB\n\ +BQADgY0AMIGJAoGBAMrx4VdcBEWSXdOa7nJr6Vh53TDfnqhgOGRUC8c+kGUu45Cp\n\ +hcGU7q44zfqvEdgkVBK+Y6GBMrbB0TALo2zK4RVDIgTc8UskbiBjiP4cHB+Zl460\n\ +kU/0vKZPWt7yWq9g87lppEr/f0RTGrKkkcVadCxmKILr4ZtS9563xXH+kKAlAgMB\n\ +AAGjUzBRMB0GA1UdDgQWBBQBroKxSi+l6RqOD5jQGRYyoM0I1jAfBgNVHSMEGDAW\n\ +gBQBroKxSi+l6RqOD5jQGRYyoM0I1jAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3\n\ +DQEBCwUAA4GBAC1f+n4ly876nTXMjdINH8qmxrHOH55vt7v1KYWqCVFSJbqtQMlT\n\ +E9+bqRGN2LpzMBkDdNkGSrCesI1l/FUStjqdpBGMi1fqFDNDyBXkLJDH5HAMR3ei\n\ +hajHIasdGWcAfj+Cyuk1KcTIEkBfdYR6a8C4g04Vbg6M0qEjFl5UTMwm\n\ +-----END CERTIFICATE-----"; + + /* THIS CHUNK OF BYTES IS AUTOMATICALLY GENERATED */ + static const unsigned char data_der[] = { + 0x30, 0x82, 0x02, 0xf2, 0x30, 0x82, 0x02, 0x5b, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x3e, + 0x03, 0xd9, 0x79, 0x86, 0xae, 0xa4, 0x85, 0x59, 0xd6, 0x2b, 0x53, 0x29, 0xee, 0xfd, 0x2c, 0x26, + 0xe8, 0x72, 0x57, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x05, 0x00, 0x30, 0x81, 0x8a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x50, 0x4c, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0b, 0x4d, 0x61, 0x7a, + 0x6f, 0x77, 0x69, 0x65, 0x63, 0x6b, 0x69, 0x65, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0c, 0x06, 0x57, 0x61, 0x72, 0x73, 0x61, 0x77, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x0c, 0x07, 0x53, 0x61, 0x6d, 0x73, 0x75, 0x6e, 0x67, 0x31, 0x0b, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x02, 0x49, 0x54, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0c, 0x0b, 0x73, 0x61, 0x6d, 0x73, 0x75, 0x6e, 0x67, 0x2e, 0x63, 0x6f, 0x6d, 0x31, 0x1f, + 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, + 0x6f, 0x6e, 0x65, 0x40, 0x73, 0x61, 0x6d, 0x73, 0x75, 0x6e, 0x67, 0x2e, 0x63, 0x6f, 0x6d, 0x30, + 0x1e, 0x17, 0x0d, 0x32, 0x30, 0x30, 0x34, 0x31, 0x34, 0x31, 0x35, 0x32, 0x33, 0x30, 0x37, 0x5a, + 0x17, 0x0d, 0x32, 0x31, 0x30, 0x34, 0x31, 0x34, 0x31, 0x35, 0x32, 0x33, 0x30, 0x37, 0x5a, 0x30, + 0x81, 0x8a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x50, 0x4c, 0x31, + 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0b, 0x4d, 0x61, 0x7a, 0x6f, 0x77, 0x69, + 0x65, 0x63, 0x6b, 0x69, 0x65, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x06, + 0x57, 0x61, 0x72, 0x73, 0x61, 0x77, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, + 0x07, 0x53, 0x61, 0x6d, 0x73, 0x75, 0x6e, 0x67, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x0b, 0x0c, 0x02, 0x49, 0x54, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0b, + 0x73, 0x61, 0x6d, 0x73, 0x75, 0x6e, 0x67, 0x2e, 0x63, 0x6f, 0x6d, 0x31, 0x1f, 0x30, 0x1d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x6e, 0x65, + 0x40, 0x73, 0x61, 0x6d, 0x73, 0x75, 0x6e, 0x67, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x81, 0x9f, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, + 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xc9, 0x73, 0x11, 0x8f, 0x63, 0x4d, 0xaa, + 0x8e, 0xc5, 0xb5, 0x6d, 0x9c, 0xea, 0x30, 0x43, 0xb5, 0x5d, 0xd3, 0xb2, 0x9c, 0x59, 0x23, 0xdf, + 0xa8, 0x69, 0xe6, 0x0d, 0xfe, 0x0a, 0xdb, 0xce, 0x22, 0x64, 0x15, 0x02, 0xf6, 0xa4, 0xe9, 0x22, + 0x04, 0xce, 0x73, 0x9e, 0x89, 0x1e, 0x87, 0x93, 0x31, 0x07, 0x91, 0x0e, 0xbd, 0x98, 0x45, 0x3d, + 0x66, 0xe9, 0x59, 0x02, 0xfc, 0x2f, 0xd9, 0x11, 0x71, 0xc4, 0x11, 0x3f, 0x20, 0xf3, 0x49, 0xb6, + 0x59, 0x26, 0xb2, 0x8c, 0x9f, 0x74, 0xe0, 0x09, 0x3b, 0x4f, 0xdd, 0xf4, 0x13, 0x8b, 0x91, 0x48, + 0x1e, 0x1b, 0xf5, 0x86, 0xca, 0xe6, 0xd6, 0x1d, 0x29, 0x74, 0x1d, 0xb6, 0x84, 0x0b, 0x48, 0xe7, + 0x40, 0x14, 0x60, 0x65, 0xb2, 0x35, 0xf0, 0x48, 0xe9, 0x93, 0xea, 0x77, 0x63, 0x77, 0x53, 0x77, + 0xaf, 0xbb, 0xac, 0xc2, 0x86, 0x40, 0xc7, 0xb0, 0x0b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, + 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xd0, 0xb1, 0x78, + 0xed, 0xee, 0xb4, 0x57, 0x7b, 0x4f, 0xed, 0x45, 0xba, 0x0b, 0x5a, 0x32, 0xe5, 0xe1, 0x32, 0xee, + 0x83, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xd0, 0xb1, + 0x78, 0xed, 0xee, 0xb4, 0x57, 0x7b, 0x4f, 0xed, 0x45, 0xba, 0x0b, 0x5a, 0x32, 0xe5, 0xe1, 0x32, + 0xee, 0x83, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, + 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x2e, 0xf4, 0x42, 0x8b, 0xde, 0xfe, 0x36, 0x79, 0x6d, 0xaa, + 0x51, 0x85, 0x65, 0xe3, 0x0f, 0x89, 0x1f, 0x84, 0xce, 0x5c, 0x34, 0x03, 0x0d, 0x59, 0x2a, 0xad, + 0xfb, 0x09, 0xd2, 0xcd, 0xbc, 0xac, 0x51, 0x4a, 0xe3, 0xcb, 0x9e, 0xe5, 0x75, 0x26, 0x36, 0x5e, + 0xe7, 0xc6, 0x86, 0x6b, 0xf8, 0xc4, 0x96, 0x99, 0x43, 0xb6, 0x53, 0xcc, 0x6a, 0x14, 0x57, 0xcd, + 0x08, 0xad, 0x53, 0x11, 0x5f, 0x17, 0x97, 0xb3, 0x2f, 0x36, 0xbe, 0xd6, 0x5c, 0x03, 0x32, 0xe3, + 0x2a, 0x4f, 0x69, 0x85, 0xf6, 0xf0, 0x14, 0x13, 0x2b, 0xfc, 0xa6, 0x64, 0x67, 0x4d, 0x7b, 0xab, + 0xb9, 0xd0, 0x06, 0x00, 0xce, 0xc6, 0x85, 0x08, 0x45, 0xfb, 0xca, 0x70, 0x1b, 0xb4, 0x8f, 0x4e, + 0x49, 0x2e, 0xfe, 0x94, 0xd7, 0x7b, 0xf1, 0xc6, 0x60, 0x24, 0xa6, 0x79, 0x5a, 0xeb, 0x92, 0xed, + 0xd7, 0x07, 0x42, 0x65, 0xd3, 0x31 + }; + + auto test_code = []() + { + int ret; + yaca_key_h key_pem = YACA_KEY_NULL, key_der = YACA_KEY_NULL; + + ret = yaca_key_import(YACA_KEY_TYPE_RSA_PUB, NULL, data_pem, + sizeof(data_pem), &key_pem); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_key_import(YACA_KEY_TYPE_RSA_PUB, NULL, (char*)data_der, + sizeof(data_der), &key_der); + if (ret != YACA_ERROR_NONE) goto exit; + + exit: + yaca_key_destroy(key_pem); + yaca_key_destroy(key_der); + return ret; + }; + + call_mock_test(test_code); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/mock_test_rsa.cpp b/tests/mock_test_rsa.cpp new file mode 100644 index 0000000..0fd2afb --- /dev/null +++ b/tests/mock_test_rsa.cpp @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Pawelczyk + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file test_rsa.c + * @author Lukasz Pawelczyk + * @brief RSA API unit tests. + */ + +#include +#include + +#include +#include +#include +#include + +#include "common.h" + + +BOOST_AUTO_TEST_SUITE(MOCK_TESTS_RSA) + +BOOST_FIXTURE_TEST_CASE(T1401__mock__negative__private_encrypt, InitFixture) +{ + struct rsa_args { + yaca_padding_e pad; + yaca_key_bit_length_e bit_len; + size_t shorter; + }; + + const std::vector rargs = { + {YACA_PADDING_NONE, YACA_KEY_LENGTH_512BIT, 0}, + {YACA_PADDING_PKCS1, YACA_KEY_LENGTH_512BIT, 11}, + }; + + for (const auto &ra: rargs) { + auto test_code = [&ra]() + { + int ret; + yaca_key_h rsa_prv = YACA_KEY_NULL, rsa_pub = YACA_KEY_NULL; + size_t input_len = ra.bit_len / 8 - ra.shorter; + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len, decrypted_len; + + ret = yaca_key_generate(YACA_KEY_TYPE_RSA_PRIV, ra.bit_len, &rsa_prv); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_key_extract_public(rsa_prv, &rsa_pub); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_rsa_private_encrypt(ra.pad, rsa_prv, INPUT_DATA, input_len, + &encrypted, &encrypted_len); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_rsa_public_decrypt(ra.pad, rsa_pub, encrypted, encrypted_len, + &decrypted, &decrypted_len); + if (ret != YACA_ERROR_NONE) goto exit; + + exit: + yaca_key_destroy(rsa_prv); + yaca_key_destroy(rsa_pub); + yaca_free(encrypted); + yaca_free(decrypted); + return ret; + }; + + call_mock_test(test_code); + } +} + +BOOST_FIXTURE_TEST_CASE(T1402__mock__negative__public_encrypt, InitFixture) +{ + struct rsa_args { + yaca_padding_e pad; + yaca_key_bit_length_e bit_len; + size_t shorter; + }; + + const std::vector rargs = { + {YACA_PADDING_NONE, YACA_KEY_LENGTH_512BIT, 0}, + {YACA_PADDING_PKCS1, YACA_KEY_LENGTH_1024BIT, 11}, + {YACA_PADDING_PKCS1_OAEP, YACA_KEY_LENGTH_2048BIT, 42}, + }; + + for (const auto &ra: rargs) { + auto test_code = [&ra]() + { + int ret; + yaca_key_h rsa_prv = YACA_KEY_NULL, rsa_pub = YACA_KEY_NULL; + size_t input_len = ra.bit_len / 8 - ra.shorter; + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len, decrypted_len; + + ret = yaca_key_generate(YACA_KEY_TYPE_RSA_PRIV, ra.bit_len, &rsa_prv); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_key_extract_public(rsa_prv, &rsa_pub); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_rsa_public_encrypt(ra.pad, rsa_pub, INPUT_DATA, input_len, + &encrypted, &encrypted_len); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_rsa_private_decrypt(ra.pad, rsa_prv, encrypted, encrypted_len, + &decrypted, &decrypted_len); + if (ret != YACA_ERROR_NONE) goto exit; + + exit: + yaca_key_destroy(rsa_prv); + yaca_key_destroy(rsa_pub); + yaca_free(encrypted); + yaca_free(decrypted); + return ret; + }; + + call_mock_test(test_code); + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/mock_test_seal.cpp b/tests/mock_test_seal.cpp new file mode 100644 index 0000000..cccc7e1 --- /dev/null +++ b/tests/mock_test_seal.cpp @@ -0,0 +1,558 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Pawelczyk + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file test_seal.cpp + * @author Lukasz Pawelczyk + * @brief Seal API unit tests. + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "common.h" + + +BOOST_AUTO_TEST_SUITE(MOCK_TESTS_SEAL) + +BOOST_FIXTURE_TEST_CASE(T1701__mock__negative__seal_open, InitFixture) +{ + struct seal_args { + yaca_encrypt_algorithm_e algo; + yaca_block_cipher_mode_e bcm; + size_t key_bit_len; + yaca_padding_e padding; + }; + + const std::vector sargs = { + {YACA_ENCRYPT_AES, YACA_BCM_CBC, 128, YACA_PADDING_NONE }, + {YACA_ENCRYPT_UNSAFE_DES, YACA_BCM_ECB, 64, YACA_PADDING_PKCS7 }, + {YACA_ENCRYPT_UNSAFE_3DES_2TDEA, YACA_BCM_CFB, 128, YACA_INVALID_PADDING}, + {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_CBC, 192, YACA_PADDING_PKCS7 }, + {YACA_ENCRYPT_UNSAFE_RC4, YACA_BCM_NONE, 256, YACA_INVALID_PADDING}, + {YACA_ENCRYPT_CAST5, YACA_BCM_CBC, 128, YACA_PADDING_NONE }, + }; + + for (const auto &sa: sargs) { + auto test_code = [&sa]() + { + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key_prv = YACA_KEY_NULL, key_pub = YACA_KEY_NULL; + yaca_key_h key_sym = YACA_KEY_NULL, iv = YACA_KEY_NULL; + + size_t len1 = 0, len2 = 0; + + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len = 0, decrypted_len = 0; + + ret = yaca_key_generate(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_512BIT, &key_prv); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_key_extract_public(key_prv, &key_pub); + if (ret != YACA_ERROR_NONE) goto exit; + + /* SEAL */ + { + ret = yaca_seal_initialize(&ctx, key_pub, sa.algo, sa.bcm, + sa.key_bit_len, &key_sym, &iv); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_get_output_length(ctx, INPUT_DATA_SIZE, &len1); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_context_get_output_length(ctx, 0, &len2); + if (ret != YACA_ERROR_NONE) goto exit; + + size_t total = len1 + len2; + size_t written; + + ret = yaca_zalloc(total, (void**)&encrypted); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_seal_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + if (ret != YACA_ERROR_NONE) goto exit; + encrypted_len = written; + + if (sa.padding != YACA_INVALID_PADDING) { + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, &sa.padding, + sizeof(yaca_padding_e)); + if (ret != YACA_ERROR_NONE) goto exit; + } + + ret = yaca_seal_finalize(ctx, encrypted + encrypted_len, &written); + if (ret != YACA_ERROR_NONE) goto exit; + encrypted_len += written; + + ret = yaca_realloc(encrypted_len, (void **)&encrypted); + if (ret != YACA_ERROR_NONE) goto exit; + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* OPEN */ + { + ret = yaca_open_initialize(&ctx, key_prv, sa.algo, sa.bcm, + sa.key_bit_len, key_sym, iv); + if (ret != YACA_ERROR_NONE) goto exit; + + if (sa.padding != YACA_INVALID_PADDING) { + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, &sa.padding, + sizeof(yaca_padding_e)); + if (ret != YACA_ERROR_NONE) goto exit; + } + + ret = yaca_context_get_output_length(ctx, encrypted_len, &len1); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_context_get_output_length(ctx, 0, &len2); + if (ret != YACA_ERROR_NONE) goto exit; + + size_t total = len1 + len2; + size_t written; + + ret = yaca_zalloc(total, (void**)&decrypted); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, &written); + if (ret != YACA_ERROR_NONE) goto exit; + decrypted_len = written; + + ret = yaca_open_finalize(ctx, decrypted + decrypted_len, &written); + if (ret != YACA_ERROR_NONE) goto exit; + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + exit: + yaca_context_destroy(ctx); + yaca_key_destroy(key_prv); + yaca_key_destroy(key_pub); + yaca_key_destroy(key_sym); + yaca_key_destroy(iv); + yaca_free(encrypted); + yaca_free(decrypted); + return ret; + }; + + call_mock_test(test_code); + } +} + +BOOST_FIXTURE_TEST_CASE(T1702__mock__negative__seal_open_rc2, InitFixture) +{ + struct seal_args { + yaca_block_cipher_mode_e bcm; + size_t key_bit_len; + size_t effective_key_bits; + }; + + const std::vector sargs = { + {YACA_BCM_CBC, 192, 1024}, + {YACA_BCM_CFB, 192, 333} + }; + + for (const auto &sa: sargs) { + auto test_code = [&sa]() + { + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key_prv = YACA_KEY_NULL, key_pub = YACA_KEY_NULL; + yaca_key_h key_sym = YACA_KEY_NULL, iv = YACA_KEY_NULL; + + size_t len1 = 0, len2 = 0; + + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len = 0, decrypted_len = 0; + + ret = yaca_key_generate(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_512BIT, &key_prv); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_key_extract_public(key_prv, &key_pub); + if (ret != YACA_ERROR_NONE) goto exit; + + /* SEAL */ + { + ret = yaca_seal_initialize(&ctx, key_pub, YACA_ENCRYPT_UNSAFE_RC2, sa.bcm, + sa.key_bit_len, &key_sym, &iv); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_RC2_EFFECTIVE_KEY_BITS, + &sa.effective_key_bits, sizeof(size_t)); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_get_output_length(ctx, INPUT_DATA_SIZE, &len1); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_context_get_output_length(ctx, 0, &len2); + if (ret != YACA_ERROR_NONE) goto exit; + + size_t total = len1 + len2; + size_t written; + + ret = yaca_zalloc(total, (void**)&encrypted); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_seal_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + if (ret != YACA_ERROR_NONE) goto exit; + encrypted_len = written; + + ret = yaca_seal_finalize(ctx, encrypted + encrypted_len, &written); + if (ret != YACA_ERROR_NONE) goto exit; + encrypted_len += written; + + ret = yaca_realloc(encrypted_len, (void **)&encrypted); + if (ret != YACA_ERROR_NONE) goto exit; + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* OPEN */ + { + ret = yaca_open_initialize(&ctx, key_prv, YACA_ENCRYPT_UNSAFE_RC2, sa.bcm, + sa.key_bit_len, key_sym, iv); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_RC2_EFFECTIVE_KEY_BITS, + &sa.effective_key_bits, sizeof(size_t)); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_get_output_length(ctx, encrypted_len, &len1); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_context_get_output_length(ctx, 0, &len2); + if (ret != YACA_ERROR_NONE) goto exit; + + size_t total = len1 + len2; + size_t written; + + ret = yaca_zalloc(total, (void**)&decrypted); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, &written); + if (ret != YACA_ERROR_NONE) goto exit; + decrypted_len = written; + + ret = yaca_open_finalize(ctx, decrypted + decrypted_len, &written); + if (ret != YACA_ERROR_NONE) goto exit; + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + exit: + yaca_context_destroy(ctx); + yaca_key_destroy(key_prv); + yaca_key_destroy(key_pub); + yaca_key_destroy(key_sym); + yaca_key_destroy(iv); + yaca_free(encrypted); + yaca_free(decrypted); + return ret; + }; + + call_mock_test(test_code); + } +} + +BOOST_FIXTURE_TEST_CASE(T1703__mock__negative__open_seal_ccm, InitFixture) +{ + struct seal_args { + size_t key_bit_len; + size_t ccm_tag_len; + size_t aad_len; + }; + + const std::vector sargs = { + {128, 6, 23}, + {256, 12, 33} + }; + + for (const auto &sa: sargs) { + auto test_code = [&sa]() + { + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key_prv = YACA_KEY_NULL, key_pub = YACA_KEY_NULL; + yaca_key_h key_sym = YACA_KEY_NULL, iv = YACA_KEY_NULL; + + size_t len1, len2; + + char *tag = NULL, *aad = NULL; + size_t tag_len; + + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len, decrypted_len; + + ret = yaca_key_generate(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_512BIT, &key_prv); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_key_extract_public(key_prv, &key_pub); + if (ret != YACA_ERROR_NONE) goto exit; + + /* SEAL */ + { + ret = yaca_seal_initialize(&ctx, key_pub, YACA_ENCRYPT_AES, YACA_BCM_CCM, + sa.key_bit_len, &key_sym, &iv); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_get_output_length(ctx, INPUT_DATA_SIZE, &len1); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_context_get_output_length(ctx, 0, &len2); + if (ret != YACA_ERROR_NONE) goto exit; + + size_t total = len1 + len2; + size_t written; + + ret = yaca_zalloc(total, (void**)&encrypted); + if (ret != YACA_ERROR_NONE) goto exit; + + tag_len = sa.ccm_tag_len; + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG_LEN, + &tag_len, sizeof(tag_len)); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_malloc(sa.aad_len, (void**)&aad); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_randomize_bytes(aad, sa.aad_len); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_seal_update(ctx, NULL, INPUT_DATA_SIZE, + NULL, &written); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, + aad, sa.aad_len); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_seal_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + if (ret != YACA_ERROR_NONE) goto exit; + encrypted_len = written; + + ret = yaca_seal_finalize(ctx, encrypted + encrypted_len, &written); + if (ret != YACA_ERROR_NONE) goto exit; + encrypted_len += written; + + ret = yaca_realloc(encrypted_len, (void **)&encrypted); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_get_property(ctx, YACA_PROPERTY_CCM_TAG, (void**)&tag, &tag_len); + if (ret != YACA_ERROR_NONE) goto exit; + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* OPEN */ + { + ret = yaca_open_initialize(&ctx, key_prv, YACA_ENCRYPT_AES, YACA_BCM_CCM, + sa.key_bit_len, key_sym, iv); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_get_output_length(ctx, encrypted_len, &len1); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_context_get_output_length(ctx, 0, &len2); + if (ret != YACA_ERROR_NONE) goto exit; + + size_t total = len1 + len2; + size_t written; + + ret = yaca_zalloc(total, (void**)&decrypted); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG, tag, tag_len); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_open_update(ctx, NULL, encrypted_len, + NULL, &written); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, + aad, sa.aad_len); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, &written); + if (ret != YACA_ERROR_NONE) goto exit; + decrypted_len = written; + + ret = yaca_open_finalize(ctx, decrypted + decrypted_len, &written); + if (ret != YACA_ERROR_NONE) goto exit; + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + exit: + yaca_context_destroy(ctx); + yaca_key_destroy(key_prv); + yaca_key_destroy(key_pub); + yaca_key_destroy(key_sym); + yaca_key_destroy(iv); + yaca_free(encrypted); + yaca_free(decrypted); + yaca_free(tag); + yaca_free(aad); + return ret; + }; + + call_mock_test(test_code); + } +} + +BOOST_FIXTURE_TEST_CASE(T1704__mock__negative__seal_open_gcm, InitFixture) +{ + struct seal_args { + size_t key_bit_len; + size_t gcm_tag_len; + size_t aad_len; + }; + + const std::vector sargs = { + {128, 13, 22}, + {192, 15, 33} + }; + + for (const auto &sa: sargs) { + auto test_code = [&sa]() + { + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key_prv = YACA_KEY_NULL, key_pub = YACA_KEY_NULL; + yaca_key_h key_sym = YACA_KEY_NULL, iv = YACA_KEY_NULL; + + size_t len1 = 0, len2 = 0; + + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len = 0, decrypted_len = 0; + + char *tag = NULL, *aad = NULL; + size_t tag_len; + + ret = yaca_key_generate(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_512BIT, &key_prv); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_key_extract_public(key_prv, &key_pub); + if (ret != YACA_ERROR_NONE) goto exit; + + /* SEAL */ + { + ret = yaca_seal_initialize(&ctx, key_pub, YACA_ENCRYPT_AES, YACA_BCM_GCM, + sa.key_bit_len, &key_sym, &iv); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_get_output_length(ctx, INPUT_DATA_SIZE, &len1); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_context_get_output_length(ctx, 0, &len2); + if (ret != YACA_ERROR_NONE) goto exit; + + size_t total = len1 + len2; + size_t written; + + ret = yaca_zalloc(total, (void**)&encrypted); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_malloc(sa.aad_len, (void**)&aad); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_randomize_bytes(aad, sa.aad_len); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_AAD, + aad, sa.aad_len); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_seal_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written); + if (ret != YACA_ERROR_NONE) goto exit; + encrypted_len = written; + + ret = yaca_seal_finalize(ctx, encrypted + encrypted_len, &written); + if (ret != YACA_ERROR_NONE) goto exit; + encrypted_len += written; + + ret = yaca_realloc(encrypted_len, (void **)&encrypted); + if (ret != YACA_ERROR_NONE) goto exit; + + tag_len = sa.gcm_tag_len; + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_TAG_LEN, + &tag_len, sizeof(tag_len)); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_get_property(ctx, YACA_PROPERTY_GCM_TAG, + (void**)&tag, &tag_len); + if (ret != YACA_ERROR_NONE) goto exit; + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* OPEN */ + { + ret = yaca_open_initialize(&ctx, key_prv, YACA_ENCRYPT_AES, YACA_BCM_GCM, + sa.key_bit_len, key_sym, iv); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_get_output_length(ctx, encrypted_len, &len1); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_context_get_output_length(ctx, 0, &len2); + if (ret != YACA_ERROR_NONE) goto exit; + + size_t total = len1 + len2; + size_t written; + + ret = yaca_zalloc(total, (void**)&decrypted); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_AAD, + aad, sa.aad_len); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, &written); + if (ret != YACA_ERROR_NONE) goto exit; + decrypted_len = written; + + ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_TAG, + tag, tag_len); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_open_finalize(ctx, decrypted + decrypted_len, &written); + if (ret != YACA_ERROR_NONE) goto exit; + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + exit: + yaca_context_destroy(ctx); + yaca_key_destroy(key_prv); + yaca_key_destroy(key_pub); + yaca_key_destroy(key_sym); + yaca_key_destroy(iv); + yaca_free(encrypted); + yaca_free(decrypted); + yaca_free(tag); + yaca_free(aad); + return ret; + }; + + call_mock_test(test_code); + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/mock_test_sign.cpp b/tests/mock_test_sign.cpp new file mode 100644 index 0000000..59aad1e --- /dev/null +++ b/tests/mock_test_sign.cpp @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Pawelczyk + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file test_sign.cpp + * @author Lukasz Pawelczyk + * @brief Signature API unit tests. + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "common.h" + + +BOOST_AUTO_TEST_SUITE(MOCK_TESTS_SIGN) + +BOOST_FIXTURE_TEST_CASE(T1801__mock__negative__sign_verify, InitFixture) +{ + struct sign_args { + yaca_key_type_e type_prv; + yaca_key_type_e type_pub; + yaca_key_bit_length_e len; + yaca_digest_algorithm_e digest; + yaca_padding_e pad; + }; + + const std::vector sargs = { + {YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_TYPE_RSA_PUB, YACA_KEY_LENGTH_512BIT, + YACA_DIGEST_SHA1, YACA_PADDING_X931}, + {YACA_KEY_TYPE_DSA_PRIV, YACA_KEY_TYPE_DSA_PUB, YACA_KEY_LENGTH_512BIT, + YACA_DIGEST_SHA224, YACA_INVALID_PADDING}, + {YACA_KEY_TYPE_EC_PRIV, YACA_KEY_TYPE_EC_PUB, + (yaca_key_bit_length_e)YACA_KEY_LENGTH_EC_PRIME192V1, + YACA_DIGEST_SHA384, YACA_INVALID_PADDING} + }; + + for (const auto &sa: sargs) { + auto test_code = [&sa]() -> int + { + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key_prv = YACA_KEY_NULL, key_pub = YACA_KEY_NULL; + + char *signature = NULL; + size_t signature_len; + + ret = yaca_key_generate(sa.type_prv, sa.len, &key_prv); + if (ret != YACA_ERROR_NONE) goto exit; + ret = yaca_key_extract_public(key_prv, &key_pub); + if (ret != YACA_ERROR_NONE) goto exit; + + /* SIGN */ + { + ret = yaca_sign_initialize(&ctx, sa.digest, key_prv); + if (ret != YACA_ERROR_NONE) goto exit; + + if (sa.pad != YACA_INVALID_PADDING) { + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &sa.pad, sizeof(sa.pad)); + if (ret != YACA_ERROR_NONE) goto exit; + } + + ret = yaca_sign_update(ctx, INPUT_DATA, INPUT_DATA_SIZE); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_get_output_length(ctx, 0, &signature_len); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_malloc(signature_len, (void **)&signature); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_sign_finalize(ctx, signature, &signature_len); + if (ret != YACA_ERROR_NONE) goto exit; + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + /* VERIFY */ + { + ret = yaca_verify_initialize(&ctx, sa.digest, key_pub); + if (ret != YACA_ERROR_NONE) goto exit; + + if (sa.pad != YACA_INVALID_PADDING) { + ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, + &sa.pad, sizeof(sa.pad)); + if (ret != YACA_ERROR_NONE) goto exit; + } + + ret = yaca_verify_update(ctx, INPUT_DATA, INPUT_DATA_SIZE); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_verify_finalize(ctx, signature, signature_len); + if (ret != YACA_ERROR_NONE) goto exit; + + yaca_context_destroy(ctx); + ctx = YACA_CONTEXT_NULL; + } + + exit: + yaca_context_destroy(ctx); + yaca_key_destroy(key_prv); + yaca_key_destroy(key_pub); + yaca_free(signature); + return ret; + }; + + call_mock_test(test_code); + } +} + +BOOST_FIXTURE_TEST_CASE(T1802__mock__negative__sign_cmac, InitFixture) +{ + struct cmac_args { + yaca_key_type_e type; + yaca_key_bit_length_e len; + yaca_encrypt_algorithm_e algo; + }; + + const std::vector cargs = { + {YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_UNSAFE_64BIT, + YACA_ENCRYPT_UNSAFE_DES}, + {YACA_KEY_TYPE_DES, YACA_KEY_LENGTH_192BIT, + YACA_ENCRYPT_3DES_3TDEA} + }; + + for (const auto &ca: cargs) { + auto test_code = [&ca]() -> int + { + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key = YACA_KEY_NULL; + + char *signature = NULL; + size_t signature_len; + + ret = yaca_key_generate(ca.type, ca.len, &key); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_sign_initialize_cmac(&ctx, ca.algo, key); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_sign_update(ctx, INPUT_DATA, INPUT_DATA_SIZE); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_get_output_length(ctx, 0, &signature_len); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_malloc(signature_len, (void **)&signature); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_sign_finalize(ctx, signature, &signature_len); + if (ret != YACA_ERROR_NONE) goto exit; + + exit: + yaca_context_destroy(ctx); + yaca_key_destroy(key); + yaca_free(signature); + return ret; + }; + + call_mock_test(test_code); + } +} + +BOOST_FIXTURE_TEST_CASE(T1803__mock__negative__sign_hmac, InitFixture) +{ + struct hmac_args { + yaca_key_type_e type; + yaca_key_bit_length_e len; + yaca_digest_algorithm_e digest; + }; + + const std::vector hargs = { + {YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_UNSAFE_128BIT, + YACA_DIGEST_SHA1}, + {YACA_KEY_TYPE_DES, YACA_KEY_LENGTH_UNSAFE_128BIT, + YACA_DIGEST_SHA224} + }; + + for (const auto &ha: hargs) { + auto test_code = [&ha]() -> int + { + int ret; + yaca_context_h ctx = YACA_CONTEXT_NULL; + yaca_key_h key = YACA_KEY_NULL; + + char *signature = NULL; + size_t signature_len; + + ret = yaca_key_generate(ha.type, ha.len, &key); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_sign_initialize_hmac(&ctx, ha.digest, key); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_sign_update(ctx, INPUT_DATA, INPUT_DATA_SIZE); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_context_get_output_length(ctx, 0, &signature_len); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_malloc(signature_len, (void **)&signature); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_sign_finalize(ctx, signature, &signature_len); + if (ret != YACA_ERROR_NONE) goto exit; + + exit: + yaca_context_destroy(ctx); + yaca_key_destroy(key); + yaca_free(signature); + return ret; + }; + + call_mock_test(test_code); + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/mock_test_simple.cpp b/tests/mock_test_simple.cpp new file mode 100644 index 0000000..8dc2bc3 --- /dev/null +++ b/tests/mock_test_simple.cpp @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Pawelczyk + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file test_simple.cpp + * @author Lukasz Pawelczyk + * @brief Simple API unit tests. + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "common.h" + + +BOOST_AUTO_TEST_SUITE(MOCK_TESTS_SIMPLE) + +BOOST_FIXTURE_TEST_CASE(T1301__mock__negative__positive__simple_encrypt_decrypt, InitFixture) +{ + struct encrypt_args { + yaca_encrypt_algorithm_e algo; + yaca_block_cipher_mode_e bcm; + size_t key_bit_len; + }; + + const std::vector eargs = { + {YACA_ENCRYPT_AES, YACA_BCM_CBC, YACA_KEY_LENGTH_256BIT }, + {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_ECB, YACA_KEY_LENGTH_192BIT }, + {YACA_ENCRYPT_CAST5, YACA_BCM_OFB, YACA_KEY_LENGTH_UNSAFE_128BIT} + }; + + for (const auto &ea: eargs) { + auto test_case = [&ea]() -> int + { + int ret; + yaca_key_h sym = YACA_KEY_NULL, iv = YACA_KEY_NULL; + size_t iv_bit_len; + char *encrypted = NULL, *decrypted = NULL; + size_t encrypted_len, decrypted_len; + + ret = yaca_encrypt_get_iv_bit_length(ea.algo, ea.bcm, ea.key_bit_len, &iv_bit_len); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, ea.key_bit_len, &sym); + if (ret != YACA_ERROR_NONE) goto exit; + + if (iv_bit_len > 0) { + ret = yaca_key_generate(YACA_KEY_TYPE_IV, iv_bit_len, &iv); + if (ret != YACA_ERROR_NONE) goto exit; + } + + ret = yaca_simple_encrypt(ea.algo, ea.bcm, sym, iv, INPUT_DATA, INPUT_DATA_SIZE, + &encrypted, &encrypted_len); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_simple_decrypt(ea.algo, ea.bcm, sym, iv, encrypted, encrypted_len, + &decrypted, &decrypted_len); + if (ret != YACA_ERROR_NONE) goto exit; + + exit: + yaca_key_destroy(sym); + yaca_key_destroy(iv); + yaca_free(encrypted); + yaca_free(decrypted); + return ret; + }; + + call_mock_test(test_case); + } +} + +BOOST_FIXTURE_TEST_CASE(T1302__mock__negative__simple_calculate_digest, InitFixture) +{ + struct digest_args { + yaca_digest_algorithm_e algo = YACA_DIGEST_SHA256; + }; + + const std::vector dargs = { + {YACA_DIGEST_MD5}, + {YACA_DIGEST_SHA256} + }; + + for (const auto &da: dargs) { + auto test_code = [&da]() -> int + { + int ret; + char *digest = NULL; + size_t digest_len; + + ret = yaca_simple_calculate_digest(da.algo, INPUT_DATA, INPUT_DATA_SIZE, + &digest, &digest_len); + yaca_free(digest); + return ret; + }; + + call_mock_test(test_code); + } +} + +BOOST_FIXTURE_TEST_CASE(T1303__mock__negative__simple_calculate_verify_signature, InitFixture) +{ + struct signature_args { + yaca_key_type_e type; + yaca_key_bit_length_e len; + yaca_digest_algorithm_e algo; + }; + + const std::vector sargs = { + {YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_512BIT, YACA_DIGEST_MD5}, + {YACA_KEY_TYPE_DSA_PRIV, YACA_KEY_LENGTH_512BIT, YACA_DIGEST_SHA256}, + {YACA_KEY_TYPE_EC_PRIV, (yaca_key_bit_length_e)YACA_KEY_LENGTH_EC_PRIME192V1, + YACA_DIGEST_SHA224} + }; + + for (const auto &sa: sargs) { + auto test_code = [&sa]() -> int + { + int ret; + yaca_key_h key_priv = YACA_KEY_NULL; + yaca_key_h key_pub = YACA_KEY_NULL; + + char *signature = NULL; + size_t signature_len; + + ret = yaca_key_generate(sa.type, sa.len, &key_priv); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_key_extract_public(key_priv, &key_pub); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_simple_calculate_signature(sa.algo, key_priv, + INPUT_DATA, INPUT_DATA_SIZE, + &signature, &signature_len); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_simple_verify_signature(sa.algo, key_pub, + INPUT_DATA, INPUT_DATA_SIZE, + signature, signature_len); + if (ret != YACA_ERROR_NONE) goto exit; + + exit: + yaca_key_destroy(key_priv); + yaca_key_destroy(key_pub); + yaca_free(signature); + return ret; + }; + + call_mock_test(test_code); + } +} + +BOOST_FIXTURE_TEST_CASE(T1304__mock__negative__simple_calculate_hmac, InitFixture) +{ + struct hmac_args { + yaca_key_type_e type; + yaca_key_bit_length_e len; + yaca_digest_algorithm_e algo; + }; + + const std::vector hargs = { + {YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_192BIT, YACA_DIGEST_MD5}, + {YACA_KEY_TYPE_DES, YACA_KEY_LENGTH_UNSAFE_128BIT, YACA_DIGEST_SHA1} + }; + + for (const auto &ha: hargs) { + auto test_code = [&ha]() -> int + { + int ret; + yaca_key_h key = YACA_KEY_NULL; + char *mac = NULL; + size_t mac_len; + + ret = yaca_key_generate(ha.type, ha.len, &key); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_simple_calculate_hmac(ha.algo, key, + INPUT_DATA, INPUT_DATA_SIZE, + &mac, &mac_len); + if (ret != YACA_ERROR_NONE) goto exit; + + exit: + yaca_key_destroy(key); + yaca_free(mac); + return ret; + }; + + call_mock_test(test_code); + } +} + +BOOST_FIXTURE_TEST_CASE(T1305__mock__negative__simple_calculate_cmac, InitFixture) +{ + struct cmac_args { + yaca_key_type_e type; + yaca_key_bit_length_e len; + yaca_encrypt_algorithm_e algo; + }; + + const std::vector cargs = { + {YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_192BIT, YACA_ENCRYPT_AES}, + {YACA_KEY_TYPE_DES, YACA_KEY_LENGTH_UNSAFE_64BIT, YACA_ENCRYPT_UNSAFE_DES} + }; + + for (const auto &ca: cargs) { + auto test_code = [&ca]() -> int + { + int ret; + yaca_key_h key = YACA_KEY_NULL; + char *mac = NULL; + size_t mac_len; + + ret = yaca_key_generate(ca.type, ca.len, &key); + if (ret != YACA_ERROR_NONE) goto exit; + + ret = yaca_simple_calculate_cmac(ca.algo, key, + INPUT_DATA, INPUT_DATA_SIZE, + &mac, &mac_len); + if (ret != YACA_ERROR_NONE) goto exit; + + exit: + yaca_key_destroy(key); + yaca_free(mac); + return ret; + }; + + call_mock_test(test_code); + } +} + +BOOST_AUTO_TEST_SUITE_END() -- 2.7.4 From 662d5009f51115f078998dcec2c1252fc5ebace6 Mon Sep 17 00:00:00 2001 From: Tomasz Swierczek Date: Fri, 17 Jul 2020 11:35:10 +0200 Subject: [PATCH 14/16] Fix static analysis issue src/key.c: openssl_password_cb according to openssl examples, password is considered a null-terminated string (https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_default_passwd_cb.html) Change-Id: I3b2fc13043e4adb7f5885d4140453297311e74f3 --- src/key.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/key.c b/src/key.c index d94e533..1eea8d9 100644 --- a/src/key.c +++ b/src/key.c @@ -62,10 +62,11 @@ static int openssl_password_cb(char *buf, int size, UNUSED int rwflag, void *u) size_t pass_len = strlen(cb_data->password); - if (pass_len > INT_MAX || (int)pass_len > size) + if (pass_len + 1 > INT_MAX || (int)pass_len + 1 > size) return 0; memcpy(buf, cb_data->password, pass_len); + buf[pass_len] = 0; cb_data->password_requested = true; return pass_len; -- 2.7.4 From b871e78243e5fff1ebe1106c5fa5af5a19c5e77b Mon Sep 17 00:00:00 2001 From: Tomasz Swierczek Date: Fri, 17 Jul 2020 11:56:58 +0200 Subject: [PATCH 15/16] Release 0.0.6 * many small fixes uncovered during work on unit tests * new, great unit tests that cover almost entire code of the library Change-Id: I05c0b6c37d55942f1ab7d10dc58abc673f8097a3 --- CMakeLists.txt | 2 +- packaging/yaca.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c1a1f4..89f74a5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,7 @@ CMAKE_MINIMUM_REQUIRED (VERSION 2.6.2) PROJECT(yaca) -SET(VERSION "0.0.5") +SET(VERSION "0.0.6") ## pkgconfig ################################################################### INCLUDE(FindPkgConfig) diff --git a/packaging/yaca.spec b/packaging/yaca.spec index 7802567..22adaec 100644 --- a/packaging/yaca.spec +++ b/packaging/yaca.spec @@ -1,7 +1,7 @@ %{!?build_type:%define build_type "RELEASE"} Name: yaca -Version: 0.0.5 +Version: 0.0.6 Release: 0 Source0: %{name}-%{version}.tar.gz License: Apache-2.0 -- 2.7.4 From 09b31353790dad369561e958a4b34212da96169d Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Fri, 12 Mar 2021 19:26:53 +0100 Subject: [PATCH 16/16] Fix segfault found by fuzzer. Unsigned int(input_len) is casted to int(flen), this can lead to using negative value, unfortunately openssl doesn't check it. According to openssl documentation, input_len is limited by RSA key size, let's validate it in yaca to avoid segfault. Change-Id: I8e821b94794f1b5d7231df16c591fe88c12c84e2 --- src/rsa.c | 5 ++++- tests/test_rsa.cpp | 13 ++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/rsa.c b/src/rsa.c index cbd951b..054db73 100644 --- a/src/rsa.c +++ b/src/rsa.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2020 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2016-2021 Samsung Electronics Co., Ltd All Rights Reserved * * Contact: Krzysztof Jackiewicz * @@ -94,6 +94,9 @@ static int encrypt_decrypt(yaca_padding_e padding, max_len = ret; + if (input_len > max_len) + return YACA_ERROR_INVALID_PARAMETER; + ret = yaca_zalloc(max_len, (void**)&loutput); if (ret != YACA_ERROR_NONE) return ret; diff --git a/tests/test_rsa.cpp b/tests/test_rsa.cpp index 0f9e095..105c77c 100644 --- a/tests/test_rsa.cpp +++ b/tests/test_rsa.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd All Rights Reserved * * Contact: Lukasz Pawelczyk * @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -452,6 +453,11 @@ BOOST_FIXTURE_TEST_CASE(T404__negative__public_encrypt, InitDebugFixture) BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); ret = yaca_rsa_public_encrypt(YACA_PADDING_NONE, key_pub, + INPUT_DATA, UINT_MAX, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_encrypt(YACA_PADDING_NONE, key_pub, INPUT_DATA, input_len, NULL, &encrypted_len); BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); @@ -466,6 +472,11 @@ BOOST_FIXTURE_TEST_CASE(T404__negative__public_encrypt, InitDebugFixture) &encrypted_pkcs1, &encrypted_pkcs1_len); BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + ret = yaca_rsa_public_encrypt(YACA_PADDING_PKCS1, key_pub, + INPUT_DATA, UINT_MAX, + &encrypted_pkcs1, &encrypted_pkcs1_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + ret = yaca_rsa_public_encrypt(YACA_PADDING_PKCS1_OAEP, key_pub, INPUT_DATA, input_len_pkcs1_oaep + 1, &encrypted_pkcs1_oaep, &encrypted_pkcs1_oaep_len); -- 2.7.4