From e32e9176bc0e86f69cda37e0b02a2a652391cf28 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Wed, 24 Aug 2016 17:20:43 +0200 Subject: [PATCH 01/16] Key wrapping memory optimization. Change-Id: Ibf49fa12fc7f89554e5c00a0e84d0f832e686fcb --- src/encrypt.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/encrypt.c b/src/encrypt.c index 03c515a..10400a4 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -276,13 +276,14 @@ int get_wrap_output_length(const yaca_context_h ctx, size_t input_len, size_t *o return YACA_ERROR_INVALID_PARAMETER; assert(c->cipher_ctx != NULL); + bool encryption = is_encryption_op(c->op_type); int type = EVP_CIPHER_type(c->cipher_ctx->cipher); if (input_len > 0) { if (type == NID_id_aes128_wrap || type == NID_id_aes192_wrap || type == NID_id_aes256_wrap) { - *output_len = input_len + 8; + *output_len = encryption ? input_len + 8 : input_len - 8; } else if (type == NID_id_smime_alg_CMS3DESwrap) { - *output_len = input_len + 16; + *output_len = encryption ? input_len + 16 : input_len - 16; } else { assert(false); return YACA_ERROR_INTERNAL; -- 2.7.4 From 73cb9a318349bee638deb863279114dfbc39e592 Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Tue, 30 Aug 2016 15:16:16 +0200 Subject: [PATCH 02/16] Handle wrong padding in RSA public decryption Change-Id: Iac3c37d2005bfae06d80c83fe7820436eda28ac5 --- src/debug.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/debug.c b/src/debug.c index 33779b8..a229ab8 100644 --- a/src/debug.c +++ b/src/debug.c @@ -125,6 +125,7 @@ int error_handle(const char *file, int line, const char *function) switch (err) { 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): 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): case ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_NOT_ENOUGH_DATA): -- 2.7.4 From 16d271755f6bcb70d6cf66d47d3306a099df5842 Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Tue, 30 Aug 2016 16:15:45 +0200 Subject: [PATCH 03/16] Allow 1B longer input in PKCS1 padding OpenSSL documentation states that for PKCS1 padding the length of encrypted input must be less than RSA_size(rsa) - 11. In fact the code itself allows less or equal input length. Also this is what PKCS #1 standard says. Change-Id: Iab7c7e4b3c3c3c64854f9c9ec67f18f2d7c0b01c --- api/yaca/yaca_seal.h | 2 +- api/yaca/yaca_types.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api/yaca/yaca_seal.h b/api/yaca/yaca_seal.h index ac7da5c..910d6aa 100755 --- a/api/yaca/yaca_seal.h +++ b/api/yaca/yaca_seal.h @@ -53,7 +53,7 @@ extern "C" { * * @remarks The @a pub_key must be #YACA_KEY_TYPE_RSA_PUB * - * @remarks The @a sym_key_bit_len must be at least 96 bits shorter than the @a pub_key bit length + * @remarks The @a sym_key_bit_len must be at least 88 bits shorter than the @a pub_key bit length * * @remarks The @a sym_key should be released using yaca_key_destroy() * diff --git a/api/yaca/yaca_types.h b/api/yaca/yaca_types.h index 91e3d84..3afb1ca 100755 --- a/api/yaca/yaca_types.h +++ b/api/yaca/yaca_types.h @@ -649,7 +649,7 @@ typedef enum { /** * PKCS #1 v1.5 padding. Suitable for RSA sign/verify and low-level RSA operations. - * For low-level operations the input must be at least 12 bytes shorter than the key length. + * For low-level operations the input must be at least 11 bytes shorter than the key length. */ YACA_PADDING_PKCS1, @@ -672,7 +672,7 @@ typedef enum { * turns out that both parties are using #YACA_PADDING_PKCS1_SSL23 (both are communicating * using SSL2 and both are SSL3 capable) it is treated as a rollback attack and an error is * returned. Suitable for low-level RSA public_encrypt/private_decrypt operations. For - * low-level operations the input must be at least 12 bytes shorter than the key length. + * low-level operations the input must be at least 11 bytes shorter than the key length. */ YACA_PADDING_PKCS1_SSLV23, -- 2.7.4 From cf8b1b29a45cf3bec4b8b2265677a7942a18e44b Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Tue, 30 Aug 2016 10:45:21 +0200 Subject: [PATCH 04/16] Fix yaca_key_import() memory leak. Change-Id: Iec2ee8d01922e0e4b63fc6963071de3eff0b6979 --- src/key.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/key.c b/src/key.c index aeaf7a9..fd3be54 100644 --- a/src/key.c +++ b/src/key.c @@ -452,8 +452,10 @@ static int import_evp(yaca_key_h *key, if (pkey == NULL) { BIO_reset(src); pkey = PEM_read_bio_PrivateKey(src, NULL, cb, (void*)&cb_data); - if (ERROR_HANDLE() == YACA_ERROR_INVALID_PASSWORD) - return YACA_ERROR_INVALID_PASSWORD; + if (ERROR_HANDLE() == YACA_ERROR_INVALID_PASSWORD) { + ret = YACA_ERROR_INVALID_PASSWORD; + goto exit; + } imported_key_category = IMPORTED_KEY_CATEGORY_PRIVATE; password_supported = true; } @@ -491,8 +493,10 @@ static int import_evp(yaca_key_h *key, if (pkey == NULL) { BIO_reset(src); pkey = d2i_PKCS8PrivateKey_bio(src, NULL, cb, (void*)&cb_data); - if (ERROR_HANDLE() == YACA_ERROR_INVALID_PASSWORD) - return YACA_ERROR_INVALID_PASSWORD; + if (ERROR_HANDLE() == YACA_ERROR_INVALID_PASSWORD) { + ret = YACA_ERROR_INVALID_PASSWORD; + goto exit; + } imported_key_category = IMPORTED_KEY_CATEGORY_PRIVATE; password_supported = true; } @@ -550,10 +554,10 @@ static int import_evp(yaca_key_h *key, } } - BIO_free(src); - - if (pkey == NULL) - return YACA_ERROR_INVALID_PARAMETER; + if (pkey == NULL) { + ret = YACA_ERROR_INVALID_PARAMETER; + goto exit; + } /* password was given, but it was not required to perform import */ if (password != NULL && !cb_data.password_requested) { @@ -578,7 +582,8 @@ static int import_evp(yaca_key_h *key, break; default: assert(false); - return YACA_ERROR_INTERNAL; + ret = YACA_ERROR_INTERNAL; + goto exit; } if (ret != YACA_ERROR_NONE) goto exit; @@ -601,7 +606,7 @@ static int import_evp(yaca_key_h *key, exit: EVP_PKEY_free(pkey); - + BIO_free_all(src); return ret; } -- 2.7.4 From 506a1f9b45162a5b50a9a036a899c6c692c537b6 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Tue, 30 Aug 2016 15:56:45 +0200 Subject: [PATCH 05/16] Fix coding style. Change-Id: I7e40fdd1b08c7d73c607971d87565d4c6d122842 --- examples/rsa.c | 4 ++-- src/key.c | 2 +- src/rsa.c | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/rsa.c b/examples/rsa.c index 251143d..1c0487b 100644 --- a/examples/rsa.c +++ b/examples/rsa.c @@ -48,7 +48,7 @@ static int public_encrypt() /* Key generation */ ret = yaca_key_generate(YACA_KEY_TYPE_RSA_PRIV, key_bit_len, &prv_key); - if (ret!= YACA_ERROR_NONE) + if (ret != YACA_ERROR_NONE) return ret; ret = yaca_key_extract_public(prv_key, &pub_key); @@ -101,7 +101,7 @@ static int private_encrypt() /* Key generation */ ret = yaca_key_generate(YACA_KEY_TYPE_RSA_PRIV, key_bit_len, &prv_key); - if (ret!= YACA_ERROR_NONE) + if (ret != YACA_ERROR_NONE) return ret; ret = yaca_key_extract_public(prv_key, &pub_key); diff --git a/src/key.c b/src/key.c index fd3be54..de55295 100644 --- a/src/key.c +++ b/src/key.c @@ -101,7 +101,7 @@ static const struct { static const size_t KEY_TYPES_PARAMS_SIZE = sizeof(KEY_TYPES_PARAMS) / sizeof(KEY_TYPES_PARAMS[0]); #define CONVERT_TYPES_TEMPLATE(data, src_type, src, dst_type, dst) \ - static int convert_##src##_to_##dst (src_type src, dst_type *dst) \ + static int convert_##src##_to_##dst(src_type src, dst_type *dst) \ { \ assert(dst != NULL); \ size_t i; \ diff --git a/src/rsa.c b/src/rsa.c index 8d07f11..bf7e21a 100644 --- a/src/rsa.c +++ b/src/rsa.c @@ -130,7 +130,7 @@ API int yaca_rsa_public_encrypt(yaca_padding_e padding, if (pub_key == YACA_KEY_NULL || pub_key->type != YACA_KEY_TYPE_RSA_PUB) return YACA_ERROR_INVALID_PARAMETER; - switch(padding) { + switch (padding) { case YACA_PADDING_NONE: case YACA_PADDING_PKCS1: case YACA_PADDING_PKCS1_OAEP: @@ -159,7 +159,7 @@ API int yaca_rsa_private_decrypt(yaca_padding_e padding, if (prv_key == YACA_KEY_NULL || prv_key->type != YACA_KEY_TYPE_RSA_PRIV) return YACA_ERROR_INVALID_PARAMETER; - switch(padding) { + switch (padding) { case YACA_PADDING_NONE: case YACA_PADDING_PKCS1: case YACA_PADDING_PKCS1_OAEP: @@ -188,7 +188,7 @@ API int yaca_rsa_private_encrypt(yaca_padding_e padding, if (prv_key == YACA_KEY_NULL || prv_key->type != YACA_KEY_TYPE_RSA_PRIV) return YACA_ERROR_INVALID_PARAMETER; - switch(padding) { + switch (padding) { case YACA_PADDING_NONE: case YACA_PADDING_PKCS1: break; @@ -215,7 +215,7 @@ API int yaca_rsa_public_decrypt(yaca_padding_e padding, if (pub_key == YACA_KEY_NULL || pub_key->type != YACA_KEY_TYPE_RSA_PUB) return YACA_ERROR_INVALID_PARAMETER; - switch(padding) { + switch (padding) { case YACA_PADDING_NONE: case YACA_PADDING_PKCS1: break; -- 2.7.4 From 82e1e35684291484185420b5457c91bc21cdea17 Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Wed, 31 Aug 2016 11:21:43 +0200 Subject: [PATCH 06/16] Convert yaca_padding_e to value acceptable by OpenSSL Change-Id: I771de0745f9779c6058199e7edc0edc858dd6d3c --- src/encrypt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/encrypt.c b/src/encrypt.c index 10400a4..537fe42 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -746,7 +746,7 @@ int set_encrypt_property(yaca_context_h ctx, c->state == STATE_FINALIZED) return YACA_ERROR_INVALID_PARAMETER; - yaca_padding_e padding = *(yaca_padding_e*)value; + int padding = *(yaca_padding_e*)value == YACA_PADDING_NONE ? 0 : 1; if (EVP_CIPHER_CTX_set_padding(c->cipher_ctx, padding) != 1) { ERROR_DUMP(YACA_ERROR_INTERNAL); return YACA_ERROR_INTERNAL; -- 2.7.4 From 480b6484ae681ee2792e798eeeced67859b2c345 Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Wed, 31 Aug 2016 13:11:43 +0200 Subject: [PATCH 07/16] Use proper input length in encryption examples Change-Id: I0a20faf41bf2b5e7670baf6100742f851b3420ff --- examples/encrypt.c | 2 +- examples/encrypt_aes_gcm_ccm.c | 4 ++-- examples/seal.c | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/encrypt.c b/examples/encrypt.c index 2d5c2c5..f152588 100644 --- a/examples/encrypt.c +++ b/examples/encrypt.c @@ -146,7 +146,7 @@ void encrypt_advanced(const yaca_encrypt_algorithm_e algo, goto exit; /* For the update */ - if (yaca_context_get_output_length(ctx, LOREM4096_SIZE, &output_len) != YACA_ERROR_NONE) + if (yaca_context_get_output_length(ctx, enc_len, &output_len) != YACA_ERROR_NONE) goto exit; /* For the finalize */ diff --git a/examples/encrypt_aes_gcm_ccm.c b/examples/encrypt_aes_gcm_ccm.c index c823d6a..64a689f 100644 --- a/examples/encrypt_aes_gcm_ccm.c +++ b/examples/encrypt_aes_gcm_ccm.c @@ -133,7 +133,7 @@ void encrypt_decrypt_aes_gcm(void) goto exit; /* For the update */ - if (yaca_context_get_output_length(ctx, LOREM4096_SIZE, &output_len) != YACA_ERROR_NONE) + if (yaca_context_get_output_length(ctx, enc_len, &output_len) != YACA_ERROR_NONE) goto exit; /* For the finalize */ @@ -286,7 +286,7 @@ void encrypt_decrypt_aes_ccm(void) goto exit; /* For the update */ - if (yaca_context_get_output_length(ctx, LOREM4096_SIZE, &output_len) != YACA_ERROR_NONE) + if (yaca_context_get_output_length(ctx, enc_len, &output_len) != YACA_ERROR_NONE) goto exit; /* For the finalize */ diff --git a/examples/seal.c b/examples/seal.c index 7a1aaa0..c0feacf 100644 --- a/examples/seal.c +++ b/examples/seal.c @@ -100,7 +100,7 @@ void encrypt_seal(const yaca_encrypt_algorithm_e algo, goto exit; /* For the update */ - if (yaca_context_get_output_length(ctx, LOREM4096_SIZE, &output_len) != YACA_ERROR_NONE) + if (yaca_context_get_output_length(ctx, enc_len, &output_len) != YACA_ERROR_NONE) goto exit; /* For the finalize */ @@ -236,7 +236,7 @@ void encrypt_seal_aes_gcm(void) goto exit; /* For the update */ - if (yaca_context_get_output_length(ctx, LOREM4096_SIZE, &output_len) != YACA_ERROR_NONE) + if (yaca_context_get_output_length(ctx, enc_len, &output_len) != YACA_ERROR_NONE) goto exit; /* For the finalize */ @@ -391,7 +391,7 @@ void encrypt_seal_aes_ccm(void) goto exit; /* For the update */ - if (yaca_context_get_output_length(ctx, LOREM4096_SIZE, &output_len) != YACA_ERROR_NONE) + if (yaca_context_get_output_length(ctx, enc_len, &output_len) != YACA_ERROR_NONE) goto exit; /* For the finalize */ -- 2.7.4 From 60428c2b10ccec13afe901d21b87ac949ffafa4c Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Wed, 7 Sep 2016 14:56:45 +0900 Subject: [PATCH 08/16] Fix svace defects using assert() to check null is good for development but if it is used partly (using both of assert() and if condition) SVACE system detects it as defect because to checking it by if condition means there is probability that it could be null. So we should choose only one of them(To use assert() or if condition) on entire of code. Change-Id: I0da13027c650e11f88f5b06fa35d8f86d43ee879 Signed-off-by: Kyungwook Tak --- src/encrypt.c | 3 ++- src/rsa.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/encrypt.c b/src/encrypt.c index 537fe42..56b316f 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -530,7 +530,8 @@ static int encrypt_ctx_restore(struct yaca_encrypt_context_s *c) } key = key_get_simple(c->backup_ctx->sym_key); - assert(key != NULL); + if (key == NULL) + return YACA_ERROR_INVALID_PARAMETER; ret = encrypt_ctx_init(c, c->backup_ctx->cipher, key->bit_len); assert(ret != YACA_ERROR_INVALID_PARAMETER); diff --git a/src/rsa.c b/src/rsa.c index bf7e21a..277af34 100644 --- a/src/rsa.c +++ b/src/rsa.c @@ -78,7 +78,8 @@ static int encrypt_decrypt(yaca_padding_e padding, assert(lpadding != -1); lasym_key = key_get_evp(key); - assert(lasym_key != NULL); + if (lasym_key == NULL) + return YACA_ERROR_INVALID_PARAMETER; ret = EVP_PKEY_size(lasym_key->evp); if (ret <= 0) { -- 2.7.4 From 9756d47be7790c78177d99f3f571c0b0d049754d Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Fri, 26 Aug 2016 16:29:26 +0200 Subject: [PATCH 09/16] Use getrandom(2) for CSPRNG instead of OpenSSL's one In case the getrandom syscall is not available use /dev/urandom directly. Change-Id: Id1f6889fcb0db0fdd8fefbe13f4fd72c0a8fd5b9 --- src/crypto.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 119 insertions(+), 13 deletions(-) diff --git a/src/crypto.c b/src/crypto.c index 87c153c..aeb6220 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -21,15 +21,23 @@ * @brief */ +#define _GNU_SOURCE #include #include #include #include +#include +#include +#include +#include +#include +#include #include #include #include #include +#include #include #include @@ -41,6 +49,84 @@ static pthread_mutex_t *mutexes = NULL; static __thread bool current_thread_initialized = false; static size_t threads_cnt = 0; static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER; +static const RAND_METHOD *saved_rand_method = NULL; +#ifndef SYS_getrandom +static int urandom_fd = -2; +#endif /* SYS_getrandom */ + +static int getrandom_wrapper(unsigned char *buf, int num) +{ + size_t received = 0; + size_t remaining = num; + +#ifndef SYS_getrandom + if (urandom_fd == -2) + return 0; +#endif /* SYS_getrandom */ + + while (remaining > 0) { +#ifdef SYS_getrandom + ssize_t n = syscall(SYS_getrandom, buf + received, remaining, 0); +#else /* SYS_getrandom */ + ssize_t n = read(urandom_fd, buf + received, remaining); +#endif /* SYS_getrandom */ + + if (n == -1) { + if (errno == EINTR) + continue; + + return 0; + } + + received += n; + remaining -= n; + } + + return 1; +} + +static void RAND_METHOD_seed(UNUSED const void *buf, UNUSED int num) +{ +} + +static int RAND_METHOD_bytes(unsigned char *buf, int num) +{ + return getrandom_wrapper(buf, num); +} + +static void RAND_METHOD_cleanup(void) +{ +} + +static void RAND_METHOD_add(UNUSED const void *buf, UNUSED int num, UNUSED double entropy) +{ +} + +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 + char tmp; + int n = syscall(SYS_getrandom, &tmp, 1, GRND_NONBLOCK); + if (n == -1 && errno == EAGAIN) + return 0; +#endif /* SYS_getrandom */ + + return 1; +} + +static const RAND_METHOD new_rand_method = { + RAND_METHOD_seed, + RAND_METHOD_bytes, + RAND_METHOD_cleanup, + RAND_METHOD_add, + RAND_METHOD_pseudorand, + RAND_METHOD_status, +}; static void locking_callback(int mode, int type, UNUSED const char *file, UNUSED int line) { @@ -86,22 +172,39 @@ API int yaca_initialize(void) if (threads_cnt == 0) { assert(mutexes == NULL); +#ifndef SYS_getrandom + if (urandom_fd == -2) { + int fd; + + do { + fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC); + } while (fd == -1 && errno == EINTR); + + if (fd < 0) { + ret = YACA_ERROR_INTERNAL; + goto exit; + } + + urandom_fd = fd; + } +#endif /* SYS_getrandom */ + OPENSSL_init(); - /* This should never fail on a /dev/random equipped system. If it does it - * means we might need to figure out another way of a truly random seed. - * https://wiki.openssl.org/index.php/Random_Numbers + /* Use getrandom from urandom pool by default. + * As per the following: + * http://www.2uo.de/myths-about-urandom/ + * http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/ * - * Another things to maybe consider for the future: + * OpenSSL's PRNG has issues: + * https://eprint.iacr.org/2016/367.pdf + + * Some other things to check/consider for the future: * - entropy on a mobile device (no mouse/keyboard) - * - fork safety: https://wiki.openssl.org/index.php/Random_fork-safety * - hardware random generator (RdRand on new Intels, Samsung hardware?) */ - if (RAND_status() != 1) { - ERROR_DUMP(YACA_ERROR_INTERNAL); - ret = YACA_ERROR_INTERNAL; - goto exit; - } + saved_rand_method = RAND_get_rand_method(); + RAND_set_rand_method(&new_rand_method); OpenSSL_add_all_digests(); OpenSSL_add_all_ciphers(); @@ -140,11 +243,9 @@ API int yaca_initialize(void) /* * TODO: - * - We should also decide on Openssl config. + * - We should also decide on OpenSSL config. * - Here's a good tutorial for initialization and cleanup: * https://wiki.openssl.org/index.php/Library_Initialization - * - We should also initialize the entropy for random number generator: - * https://wiki.openssl.org/index.php/Random_Numbers#Initialization */ } threads_cnt++; @@ -175,6 +276,11 @@ API void yaca_cleanup(void) EVP_cleanup(); RAND_cleanup(); CRYPTO_cleanup_all_ex_data(); + RAND_set_rand_method(saved_rand_method); +#ifndef SYS_getrandom + close(urandom_fd); + urandom_fd = -2; +#endif /* SYS_getrandom */ /* threads support cleanup */ CRYPTO_set_id_callback(NULL); -- 2.7.4 From 2eb853d7299b0b0fa4162ab4a03c1de890b97e53 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Mon, 5 Sep 2016 18:50:36 +0200 Subject: [PATCH 10/16] Adapt YACA to work with OpenSSL 1.1 preserving 1.0 compatibility Change-Id: I27e199659666d2d87b17fcb9882b0e70f751c628 --- src/crypto.c | 46 +++++++++++++++++++++++++++++++++++++++------- src/debug.c | 8 +++++++- src/encrypt.c | 14 +++++++------- src/internal.h | 29 +++++++++++++++++++++++++++++ src/key.c | 8 ++++---- src/rsa.c | 2 +- src/sign.c | 26 ++++++++++++++++---------- 7 files changed, 103 insertions(+), 30 deletions(-) diff --git a/src/crypto.c b/src/crypto.c index aeb6220..a13a594 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -44,7 +44,9 @@ #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; @@ -85,16 +87,21 @@ static int getrandom_wrapper(unsigned char *buf, int num) return 1; } -static void RAND_METHOD_seed(UNUSED const void *buf, UNUSED int num) +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + +static int RAND_METHOD_seed(UNUSED const void *buf, UNUSED int num) { + return 1; } -static int RAND_METHOD_bytes(unsigned char *buf, int num) +static int RAND_METHOD_add(UNUSED const void *buf, UNUSED int num, UNUSED double entropy) { - return getrandom_wrapper(buf, num); + return 1; } -static void RAND_METHOD_cleanup(void) +#else /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ + +static void RAND_METHOD_seed(UNUSED const void *buf, UNUSED int num) { } @@ -102,6 +109,17 @@ static void RAND_METHOD_add(UNUSED const void *buf, UNUSED int num, UNUSED doubl { } +#endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ + +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); @@ -128,6 +146,8 @@ 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 @@ -159,6 +179,8 @@ static void destroy_mutexes(int count) } } +#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ + API int yaca_initialize(void) { int ret = YACA_ERROR_NONE; @@ -170,7 +192,6 @@ API int yaca_initialize(void) pthread_mutex_lock(&init_mutex); { if (threads_cnt == 0) { - assert(mutexes == NULL); #ifndef SYS_getrandom if (urandom_fd == -2) { @@ -209,7 +230,10 @@ 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); @@ -240,6 +264,7 @@ API int yaca_initialize(void) CRYPTO_set_id_callback(thread_id_callback); CRYPTO_set_locking_callback(locking_callback); } +#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ /* * TODO: @@ -251,7 +276,11 @@ API int yaca_initialize(void) threads_cnt++; current_thread_initialized = true; } + +#if OPENSSL_VERSION_NUMBER < 0x10100000L || !defined SYS_getrandom exit: +#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L || !defined SYS_getrandom */ + pthread_mutex_unlock(&init_mutex); return ret; @@ -264,7 +293,9 @@ 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); @@ -272,21 +303,22 @@ API void yaca_cleanup(void) /* last one turns off the light */ if (threads_cnt == 1) { ERR_free_strings(); - ERR_remove_thread_state(NULL); EVP_cleanup(); RAND_cleanup(); - CRYPTO_cleanup_all_ex_data(); RAND_set_rand_method(saved_rand_method); + #ifndef SYS_getrandom close(urandom_fd); 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 a229ab8..b6a113d 100644 --- a/src/debug.c +++ b/src/debug.c @@ -123,9 +123,15 @@ 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): +#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): case ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_NOT_ENOUGH_DATA): @@ -191,7 +197,7 @@ int error_handle(const char *file, int line, const char *function) /* fatal errors */ int reason = ERR_GET_REASON(err); - if (ret == YACA_ERROR_NONE && reason <= GENERIC_REASON_MAX && ERR_FATAL_ERROR(err) > 0) { + if (ret == YACA_ERROR_NONE && reason <= GENERIC_REASON_MAX && (err & ERR_R_FATAL) > 0) { switch (reason) { case ERR_R_MALLOC_FAILURE: ret = YACA_ERROR_OUT_OF_MEMORY; diff --git a/src/encrypt.c b/src/encrypt.c index 56b316f..6ce25cc 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -277,7 +277,7 @@ int get_wrap_output_length(const yaca_context_h ctx, size_t input_len, size_t *o assert(c->cipher_ctx != NULL); bool encryption = is_encryption_op(c->op_type); - int type = EVP_CIPHER_type(c->cipher_ctx->cipher); + int type = EVP_CIPHER_CTX_type(c->cipher_ctx); if (input_len > 0) { if (type == NID_id_aes128_wrap || type == NID_id_aes192_wrap || type == NID_id_aes256_wrap) { @@ -644,7 +644,7 @@ int set_encrypt_property(yaca_context_h ctx, assert(c->cipher_ctx != NULL); mode = EVP_CIPHER_CTX_mode(c->cipher_ctx); - nid = EVP_CIPHER_nid(c->cipher_ctx->cipher); + nid = EVP_CIPHER_CTX_nid(c->cipher_ctx); switch (property) { case YACA_PROPERTY_GCM_AAD: @@ -942,7 +942,7 @@ int encrypt_initialize(yaca_context_h *ctx, goto exit; mode = EVP_CIPHER_CTX_mode(nc->cipher_ctx); - nid = EVP_CIPHER_nid(nc->cipher_ctx->cipher); + nid = EVP_CIPHER_CTX_nid(nc->cipher_ctx); if (mode == EVP_CIPH_CCM_MODE || nid == NID_rc2_cbc || nid == NID_rc2_ecb || nid == NID_rc2_cfb64 || nid == NID_rc2_ofb64) { ret = encrypt_ctx_backup(nc, cipher, sym_key, iv); @@ -977,7 +977,7 @@ int encrypt_update(yaca_context_h ctx, return YACA_ERROR_INVALID_PARAMETER; mode = EVP_CIPHER_CTX_mode(c->cipher_ctx); - type = EVP_CIPHER_type(c->cipher_ctx->cipher); + type = EVP_CIPHER_CTX_type(c->cipher_ctx); enum encrypt_context_state_e target_state; if (output == NULL && input == NULL) @@ -1024,7 +1024,7 @@ int encrypt_update(yaca_context_h ctx, } /* Fix for OpenSSL error in 3DES CFB1 */ - if ((c->cipher_ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) != 0) { + if ((EVP_CIPHER_CTX_flags(c->cipher_ctx) & EVP_CIPH_FLAG_LENGTH_BITS) != 0) { if (input_len > INT_MAX / 8) return YACA_ERROR_INVALID_PARAMETER; input_len *= 8; @@ -1042,7 +1042,7 @@ int encrypt_update(yaca_context_h ctx, c->state = target_state; /* Fix for OpenSSL error in 3DES CFB1 */ - if ((c->cipher_ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) != 0) + if ((EVP_CIPHER_CTX_flags(c->cipher_ctx) & EVP_CIPH_FLAG_LENGTH_BITS) != 0) *output_len /= 8; return YACA_ERROR_NONE; @@ -1071,7 +1071,7 @@ int encrypt_finalize(yaca_context_h ctx, *output_len = loutput_len; /* Fix for OpenSSL error in 3DES CFB1 */ - if ((c->cipher_ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) != 0) + if ((EVP_CIPHER_CTX_flags(c->cipher_ctx) & EVP_CIPH_FLAG_LENGTH_BITS) != 0) *output_len /= 8; c->state = STATE_FINALIZED; diff --git a/src/internal.h b/src/internal.h index 97e86c3..20da604 100644 --- a/src/internal.h +++ b/src/internal.h @@ -29,12 +29,41 @@ #include #include +#include +#include +#include #include #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, YACA_CONTEXT_DIGEST, diff --git a/src/key.c b/src/key.c index de55295..264d5ae 100644 --- a/src/key.c +++ b/src/key.c @@ -568,7 +568,7 @@ static int import_evp(yaca_key_h *key, goto exit; } - imported_evp_id = EVP_PKEY_type(pkey->type); + imported_evp_id = EVP_PKEY_type(EVP_PKEY_id(pkey)); switch (imported_key_category) { case IMPORTED_KEY_CATEGORY_PRIVATE: @@ -1161,7 +1161,7 @@ static int generate_evp_pkey_key(int evp_id, size_t key_bit_len, EVP_PKEY *param if (ret != YACA_ERROR_NONE) return ret; } else { - CRYPTO_add(¶ms->references, 1, CRYPTO_LOCK_EVP_PKEY); + EVP_PKEY_up_ref(params); } kctx = EVP_PKEY_CTX_new(params, NULL); @@ -1359,7 +1359,7 @@ static yaca_key_h key_copy_evp(const struct yaca_key_evp_s *key) return YACA_KEY_NULL; /* raise the refcount */ - CRYPTO_add(&key->evp->references, 1, CRYPTO_LOCK_EVP_PKEY); + EVP_PKEY_up_ref(key->evp); copy->key.type = key->key.type; copy->evp = key->evp; @@ -1427,7 +1427,7 @@ API int yaca_key_get_bit_length(const yaca_key_h key, size_t *key_bit_len) case YACA_KEY_TYPE_EC_PRIV: case YACA_KEY_TYPE_EC_PUB: case YACA_KEY_TYPE_EC_PARAMS: { - assert(EVP_PKEY_type(evp_key->evp->type) == EVP_PKEY_EC); + assert(EVP_PKEY_type(EVP_PKEY_id(evp_key->evp)) == EVP_PKEY_EC); const EC_KEY *eck = EVP_PKEY_get0(evp_key->evp); const EC_GROUP *ecg = EC_KEY_get0_group(eck); diff --git a/src/rsa.c b/src/rsa.c index 277af34..334a383 100644 --- a/src/rsa.c +++ b/src/rsa.c @@ -97,7 +97,7 @@ static int encrypt_decrypt(yaca_padding_e padding, ret = fn(input_len, (const unsigned char*)input, (unsigned char*)loutput, - lasym_key->evp->pkey.rsa, + EVP_PKEY_get0_RSA(lasym_key->evp), lpadding); if (ret < 0) { diff --git a/src/sign.c b/src/sign.c index 79d7759..ea9ce6f 100644 --- a/src/sign.c +++ b/src/sign.c @@ -70,16 +70,18 @@ static int get_sign_output_length(const yaca_context_h ctx, assert(output_len != NULL); struct yaca_sign_context_s *c = get_sign_context(ctx); + EVP_PKEY_CTX *pctx; if (c == NULL || input_len != 0) return YACA_ERROR_INVALID_PARAMETER; assert(c->md_ctx != NULL); - if (c->md_ctx->pctx == NULL) + pctx = EVP_MD_CTX_pkey_ctx(c->md_ctx); + if (pctx == NULL) return YACA_ERROR_INTERNAL; - EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(c->md_ctx->pctx); + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx); if (pkey == NULL) { ERROR_DUMP(YACA_ERROR_INTERNAL); return YACA_ERROR_INTERNAL; @@ -116,13 +118,15 @@ int set_sign_property(yaca_context_h ctx, yaca_padding_e padding; int pad; EVP_PKEY *pkey; + EVP_PKEY_CTX *pctx; if (c == NULL || value == NULL) return YACA_ERROR_INVALID_PARAMETER; assert(c->md_ctx != NULL); - if (c->md_ctx->pctx == NULL) + pctx = EVP_MD_CTX_pkey_ctx(c->md_ctx); + if (pctx == NULL) return YACA_ERROR_INTERNAL; /* this function only supports padding */ @@ -143,7 +147,7 @@ int set_sign_property(yaca_context_h ctx, pad = rsa_padding2openssl(padding); assert(pad != -1); - pkey = EVP_PKEY_CTX_get0_pkey(c->md_ctx->pctx); + pkey = EVP_PKEY_CTX_get0_pkey(pctx); if (pkey == NULL) { ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); @@ -151,10 +155,10 @@ int set_sign_property(yaca_context_h ctx, } /* padding only works for RSA */ - if (pkey->type != EVP_PKEY_RSA) + if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA) return YACA_ERROR_INVALID_PARAMETER; - ret = EVP_PKEY_CTX_set_rsa_padding(c->md_ctx->pctx, pad); + ret = EVP_PKEY_CTX_set_rsa_padding(pctx, pad); if (ret <= 0) { ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); @@ -172,6 +176,7 @@ int get_sign_property(const yaca_context_h ctx, int ret; struct yaca_sign_context_s *c = get_sign_context(ctx); EVP_PKEY *pkey; + EVP_PKEY_CTX *pctx; int pad; yaca_padding_e padding; @@ -180,14 +185,15 @@ int get_sign_property(const yaca_context_h ctx, assert(c->md_ctx != NULL); - if (c->md_ctx->pctx == NULL) + pctx = EVP_MD_CTX_pkey_ctx(c->md_ctx); + if (pctx == NULL) return YACA_ERROR_INTERNAL; /* this function only supports padding */ if (property != YACA_PROPERTY_PADDING) return YACA_ERROR_INVALID_PARAMETER; - pkey = EVP_PKEY_CTX_get0_pkey(c->md_ctx->pctx); + pkey = EVP_PKEY_CTX_get0_pkey(pctx); if (pkey == NULL) { ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); @@ -195,10 +201,10 @@ int get_sign_property(const yaca_context_h ctx, } /* padding only works for RSA */ - if (pkey->type != EVP_PKEY_RSA) + if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA) return YACA_ERROR_INVALID_PARAMETER; - ret = EVP_PKEY_CTX_get_rsa_padding(c->md_ctx->pctx, &pad); + ret = EVP_PKEY_CTX_get_rsa_padding(pctx, &pad); if (ret <= 0) { ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); -- 2.7.4 From 00563004155bc8f11a51ee364d5f39f24d291d42 Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Wed, 7 Sep 2016 16:21:18 +0200 Subject: [PATCH 11/16] Fix OpenSSL 1.1 issues - 3DES CFB1 implementation is fixed but function that checks buffer overlapping ignores the input data length unit resulting in an error. It's impossible to create a code that works with both version so #if was used. - OpenSSL 1.1's EVP_CIPHER_CTX_flags() gets flags from EVP_CIPHER instead of EVP_CIPHER_CTX. Call replaced with EVP_CIPHER_CTX_test_flags(). Change-Id: Ic43fd9e02b982bc767259ad3a818314a6e319eb7 --- src/encrypt.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/encrypt.c b/src/encrypt.c index 6ce25cc..7e9fd58 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -464,10 +464,12 @@ 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; @@ -1024,7 +1026,7 @@ int encrypt_update(yaca_context_h ctx, } /* Fix for OpenSSL error in 3DES CFB1 */ - if ((EVP_CIPHER_CTX_flags(c->cipher_ctx) & EVP_CIPH_FLAG_LENGTH_BITS) != 0) { + 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; @@ -1042,7 +1044,7 @@ int encrypt_update(yaca_context_h ctx, c->state = target_state; /* Fix for OpenSSL error in 3DES CFB1 */ - if ((EVP_CIPHER_CTX_flags(c->cipher_ctx) & EVP_CIPH_FLAG_LENGTH_BITS) != 0) + if (EVP_CIPHER_CTX_test_flags(c->cipher_ctx, EVP_CIPH_FLAG_LENGTH_BITS) != 0) *output_len /= 8; return YACA_ERROR_NONE; @@ -1071,7 +1073,7 @@ int encrypt_finalize(yaca_context_h ctx, *output_len = loutput_len; /* Fix for OpenSSL error in 3DES CFB1 */ - if ((EVP_CIPHER_CTX_flags(c->cipher_ctx) & EVP_CIPH_FLAG_LENGTH_BITS) != 0) + if (EVP_CIPHER_CTX_test_flags(c->cipher_ctx, EVP_CIPH_FLAG_LENGTH_BITS) != 0) *output_len /= 8; c->state = STATE_FINALIZED; -- 2.7.4 From 16e507b029f0e6de1b4b7a3f49aac17f1f84510e Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Fri, 2 Sep 2016 15:58:07 +0200 Subject: [PATCH 12/16] GCM and CCM fixes. Change-Id: I0ddb50041c871bac78f44f34844df2259618a01f --- api/yaca/yaca_encrypt.h | 6 ++- api/yaca/yaca_seal.h | 6 ++- api/yaca/yaca_types.h | 21 +++++--- examples/encrypt_aes_gcm_ccm.c | 7 ++- examples/seal.c | 7 ++- src/encrypt.c | 116 +++++++++++++++++++++++------------------ 6 files changed, 97 insertions(+), 66 deletions(-) diff --git a/api/yaca/yaca_encrypt.h b/api/yaca/yaca_encrypt.h index 97bfe58..72b2236 100755 --- a/api/yaca/yaca_encrypt.h +++ b/api/yaca/yaca_encrypt.h @@ -199,7 +199,8 @@ int yaca_decrypt_initialize(yaca_context_h *ctx, * @return #YACA_ERROR_NONE on success, negative on error * @retval #YACA_ERROR_NONE Successful * @retval #YACA_ERROR_INVALID_PARAMETER Required parameters have incorrect values (NULL, 0, - * invalid context) + * invalid context), wrong #YACA_PROPERTY_CCM_AAD or + * wrong #YACA_PROPERTY_CCM_TAG was used * @retval #YACA_ERROR_INTERNAL Internal error * * @see yaca_decrypt_initialize() @@ -229,7 +230,8 @@ int yaca_decrypt_update(yaca_context_h ctx, * @return #YACA_ERROR_NONE on success, negative on error * @retval #YACA_ERROR_NONE Successful * @retval #YACA_ERROR_INVALID_PARAMETER Required parameters have incorrect values (NULL, - * invalid context) + * invalid context), wrong #YACA_PROPERTY_GCM_AAD or + * wrong #YACA_PROPERTY_GCM_TAG was used * @retval #YACA_ERROR_INTERNAL Internal error * * @see yaca_decrypt_initialize() diff --git a/api/yaca/yaca_seal.h b/api/yaca/yaca_seal.h index 910d6aa..c06a8b7 100755 --- a/api/yaca/yaca_seal.h +++ b/api/yaca/yaca_seal.h @@ -207,7 +207,8 @@ int yaca_open_initialize(yaca_context_h *ctx, * @return #YACA_ERROR_NONE on success, negative on error * @retval #YACA_ERROR_NONE Successful * @retval #YACA_ERROR_INVALID_PARAMETER Required parameters have incorrect values (NULL, 0, - * invalid context) + * invalid context), wrong #YACA_PROPERTY_CCM_AAD or + * wrong #YACA_PROPERTY_CCM_TAG was used * @retval #YACA_ERROR_INTERNAL Internal error * * @see yaca_open_initialize() @@ -237,7 +238,8 @@ int yaca_open_update(yaca_context_h ctx, * @return #YACA_ERROR_NONE on success, negative on error * @retval #YACA_ERROR_NONE Successful * @retval #YACA_ERROR_INVALID_PARAMETER Required parameters have incorrect values (NULL, - * invalid context) + * invalid context), wrong #YACA_PROPERTY_GCM_AAD or + * wrong #YACA_PROPERTY_GCM_TAG was used * @retval #YACA_ERROR_INTERNAL Internal error * * @see yaca_open_initialize() diff --git a/api/yaca/yaca_types.h b/api/yaca/yaca_types.h index 3afb1ca..0f0ae33 100755 --- a/api/yaca/yaca_types.h +++ b/api/yaca/yaca_types.h @@ -484,9 +484,9 @@ typedef enum { * This is a variable Initialization Vector length mode (recommended 96-bits). * * Supported properties: - * - #YACA_PROPERTY_GCM_TAG_LEN = GCM tag length\n - * Supported tag lengths: @c 4, @c 8, @c 12, @c 13, @c 14, @c 15, @c 16, - * (recommended 16 bytes tag).\n + * - #YACA_PROPERTY_GCM_TAG_LEN = GCM tag length (optional)\n + * Supported tag lengths: @c 4, @c 8, @c 12, @c 13, @c 14, @c 15, @c 16 + * (16 bytes tag by default).\n * Set after yaca_encrypt_finalize() / yaca_seal_finalize() and before * yaca_context_get_property(#YACA_PROPERTY_GCM_TAG) in encryption / seal operation.\n * The @a value should be a size_t variable.\n @@ -494,7 +494,8 @@ typedef enum { * * - #YACA_PROPERTY_GCM_TAG = GCM tag\n * Get after yaca_encrypt_finalize() / yaca_seal_finalize() in encryption / seal operation.\n - * Set before yaca_decrypt_finalize() / yaca_open_finalize() in decryption / open operation.\n\n + * Set after yaca_decrypt_update() / yaca_open_update() and before + * yaca_decrypt_finalize() / yaca_open_finalize() in decryption / open operation.\n\n * * - #YACA_PROPERTY_GCM_AAD = additional authentication data (optional)\n * Set after yaca_encrypt_initialize() / yaca_seal_initialize() and before @@ -503,6 +504,8 @@ typedef enum { * yaca_decrypt_update() / yaca_open_update() in decryption / open operation.\n\n * * @see yaca_context_set_property() + * @see yaca_context_get_property() + * */ YACA_BCM_GCM, @@ -541,8 +544,8 @@ typedef enum { * (recommended 56-bits).\n\n * * Supported properties: - * - #YACA_PROPERTY_CCM_TAG_LEN = CCM tag length\n - * Supported tag lengths: 4-16 bytes in steps of 2 bytes (recommended 12 bytes tag).\n + * - #YACA_PROPERTY_CCM_TAG_LEN = CCM tag length (optional)\n + * Supported tag lengths: 4-16 bytes in steps of 2 bytes (12 bytes tag by default).\n * Set after yaca_encrypt_initialize() / yaca_seal_initialize() and before * yaca_encrypt_update() / yaca_seal_update() in encryption / seal operation.\n * The @a value should be a size_t variable.\n @@ -564,9 +567,13 @@ typedef enum { * 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\n + * 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\n * * @see yaca_context_set_property() + * @see yaca_context_get_property() + * */ YACA_BCM_CCM, diff --git a/examples/encrypt_aes_gcm_ccm.c b/examples/encrypt_aes_gcm_ccm.c index 64a689f..05f2cfd 100644 --- a/examples/encrypt_aes_gcm_ccm.c +++ b/examples/encrypt_aes_gcm_ccm.c @@ -298,13 +298,16 @@ void encrypt_decrypt_aes_ccm(void) if (yaca_malloc(dec_len, (void**)&dec) != YACA_ERROR_NONE) goto exit; - /* The tag verify is performed when you call the final yaca_decrypt_update(), - * there is no call to yaca_decrypt_finalize() */ if (yaca_decrypt_update(ctx, enc, enc_len, dec, &written_len) != YACA_ERROR_NONE) goto exit; dec_len = written_len; + if (yaca_decrypt_finalize(ctx, dec + written_len, &written_len) != YACA_ERROR_NONE) + goto exit; + + dec_len += written_len; + printf("Decrypted data (16 of %zu bytes): %.16s\n\n", dec_len, dec); } diff --git a/examples/seal.c b/examples/seal.c index c0feacf..494c416 100644 --- a/examples/seal.c +++ b/examples/seal.c @@ -403,13 +403,16 @@ void encrypt_seal_aes_ccm(void) if (yaca_malloc(dec_len, (void**)&dec) != YACA_ERROR_NONE) goto exit; - /* The tag verify is performed when you call the final yaca_open_update(), - * there is no call to yaca_open_finalize() */ if (yaca_open_update(ctx, enc, enc_len, dec, &written_len) != YACA_ERROR_NONE) goto exit; dec_len = written_len; + if (yaca_open_finalize(ctx, dec + written_len, &written_len) != YACA_ERROR_NONE) + goto exit; + + dec_len += written_len; + printf("Decrypted data (16 of %zu bytes): %.16s\n\n", dec_len, dec); } diff --git a/src/encrypt.c b/src/encrypt.c index 7e9fd58..d343efe 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -205,6 +205,30 @@ static const size_t VALID_GCM_TAG_LENGTHS[] = { 4, 8, 12, 13, 14, 15, 16 }; static const size_t VALID_GCM_TAG_LENGTHS_LENGTH = sizeof(VALID_GCM_TAG_LENGTHS) / sizeof(VALID_GCM_TAG_LENGTHS[0]); +static const size_t VALID_CCM_TAG_LENGTHS[] = { 4, 6, 8, 10, 12, 14, 16 }; +static const size_t VALID_CCM_TAG_LENGTHS_LENGTH = + sizeof(VALID_CCM_TAG_LENGTHS) / sizeof(VALID_CCM_TAG_LENGTHS[0]); + +static bool is_valid_tag_len(int mode, size_t tag_len) +{ + switch (mode) { + case EVP_CIPH_GCM_MODE: + for (size_t i = 0; i < VALID_GCM_TAG_LENGTHS_LENGTH; i++) { + if (tag_len == VALID_GCM_TAG_LENGTHS[i]) + return true; + } + return false; + case EVP_CIPH_CCM_MODE: + for (size_t i = 0; i < VALID_CCM_TAG_LENGTHS_LENGTH; i++) { + if (tag_len == VALID_CCM_TAG_LENGTHS[i]) + return true; + } + return false; + default: + return false; + } +} + struct yaca_encrypt_context_s *get_encrypt_context(const yaca_context_h ctx) { if (ctx == YACA_CONTEXT_NULL) @@ -556,9 +580,6 @@ static int encrypt_ctx_set_ccm_tag_len(struct yaca_encrypt_context_s *c, size_t assert(c->backup_ctx != NULL); assert(is_encryption_op(c->op_type)); - if (tag_len == 0 || tag_len > INT_MAX) - return YACA_ERROR_INVALID_PARAMETER; - ret = encrypt_ctx_restore(c); if (ret != YACA_ERROR_NONE) return ret; @@ -585,9 +606,6 @@ static int encrypt_ctx_set_ccm_tag(struct yaca_encrypt_context_s *c, char *tag, assert(!is_encryption_op(c->op_type)); assert(tag != NULL); - if (tag_len == 0 || tag_len > INT_MAX) - return YACA_ERROR_INVALID_PARAMETER; - ret = encrypt_ctx_restore(c); if (ret != YACA_ERROR_NONE) return ret; @@ -650,10 +668,8 @@ int set_encrypt_property(yaca_context_h ctx, switch (property) { case YACA_PROPERTY_GCM_AAD: - if (mode != EVP_CIPH_GCM_MODE) - return YACA_ERROR_INVALID_PARAMETER; - - if (!verify_state_change(c, STATE_AAD_UPDATED)) + if (mode != EVP_CIPH_GCM_MODE || + !verify_state_change(c, STATE_AAD_UPDATED)) return YACA_ERROR_INVALID_PARAMETER; if (EVP_CipherUpdate(c->cipher_ctx, NULL, &len, value, value_len) != 1) { @@ -663,10 +679,8 @@ int set_encrypt_property(yaca_context_h ctx, c->state = STATE_AAD_UPDATED; break; case YACA_PROPERTY_CCM_AAD: - if (mode != EVP_CIPH_CCM_MODE) - return YACA_ERROR_INVALID_PARAMETER; - - if (!verify_state_change(c, STATE_AAD_UPDATED)) + if (mode != EVP_CIPH_CCM_MODE || + !verify_state_change(c, STATE_AAD_UPDATED)) return YACA_ERROR_INVALID_PARAMETER; if (EVP_CipherUpdate(c->cipher_ctx, NULL, &len, value, value_len) != 1) { @@ -677,16 +691,11 @@ int set_encrypt_property(yaca_context_h ctx, break; case YACA_PROPERTY_GCM_TAG: if (mode != EVP_CIPH_GCM_MODE || is_encryption_op(c->op_type) || - value_len == 0 || value_len > INT_MAX) - return YACA_ERROR_INVALID_PARAMETER; - - if (!verify_state_change(c, STATE_TAG_SET)) + !is_valid_tag_len(mode, value_len) || + !verify_state_change(c, STATE_TAG_SET)) return YACA_ERROR_INVALID_PARAMETER; - if (EVP_CIPHER_CTX_ctrl(c->cipher_ctx, - EVP_CTRL_GCM_SET_TAG, - value_len, - (void*)value) != 1) { + if (EVP_CIPHER_CTX_ctrl(c->cipher_ctx, EVP_CTRL_GCM_SET_TAG, value_len, (void*)value) != 1) { ERROR_DUMP(YACA_ERROR_INTERNAL); return YACA_ERROR_INTERNAL; } @@ -695,30 +704,17 @@ int set_encrypt_property(yaca_context_h ctx, case YACA_PROPERTY_GCM_TAG_LEN: if (value_len != sizeof(size_t) || mode != EVP_CIPH_GCM_MODE || !is_encryption_op(c->op_type) || - *(size_t*)value == 0 || *(size_t*)value > INT_MAX) + !is_valid_tag_len(mode, *(size_t*)value) || + !verify_state_change(c, STATE_TAG_LENGTH_SET)) return YACA_ERROR_INVALID_PARAMETER; - if (!verify_state_change(c, STATE_TAG_LENGTH_SET)) - return YACA_ERROR_INVALID_PARAMETER; - - /* check allowed tag lengths */ - { - size_t tag_len = *(size_t*)value; - for (size_t i = 0; i < VALID_GCM_TAG_LENGTHS_LENGTH; i++) { - if (tag_len == VALID_GCM_TAG_LENGTHS[i]) { - c->tag_len = tag_len; - c->state = STATE_TAG_LENGTH_SET; - return YACA_ERROR_NONE; - } - } - return YACA_ERROR_INVALID_PARAMETER; - } + c->tag_len = *(size_t*)value; + c->state = STATE_TAG_LENGTH_SET; break; case YACA_PROPERTY_CCM_TAG: - if (mode != EVP_CIPH_CCM_MODE || is_encryption_op(c->op_type)) - return YACA_ERROR_INVALID_PARAMETER; - - if (!verify_state_change(c, STATE_TAG_SET)) + if (mode != EVP_CIPH_CCM_MODE || is_encryption_op(c->op_type) || + !is_valid_tag_len(mode, value_len) || + !verify_state_change(c, STATE_TAG_SET)) return YACA_ERROR_INVALID_PARAMETER; ret = encrypt_ctx_set_ccm_tag(c, (char*)value, value_len); @@ -729,10 +725,9 @@ int set_encrypt_property(yaca_context_h ctx, break; case YACA_PROPERTY_CCM_TAG_LEN: if (value_len != sizeof(size_t) || mode != EVP_CIPH_CCM_MODE || - !is_encryption_op(c->op_type)) - return YACA_ERROR_INVALID_PARAMETER; - - if (!verify_state_change(c, STATE_TAG_LENGTH_SET)) + !is_encryption_op(c->op_type) || + !is_valid_tag_len(mode, *(size_t*)value) || + !verify_state_change(c, STATE_TAG_LENGTH_SET)) return YACA_ERROR_INVALID_PARAMETER; ret = encrypt_ctx_set_ccm_tag_len(c, *(size_t*)value); @@ -1034,8 +1029,17 @@ int encrypt_update(yaca_context_h ctx, ret = EVP_CipherUpdate(c->cipher_ctx, output, &loutput_len, input, input_len); if (ret != 1 || loutput_len < 0) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); + if (mode == EVP_CIPH_CCM_MODE && op_type == OP_DECRYPT) { + /* A non positive return value from EVP_CipherUpdate should be considered as + * a failure to authenticate ciphertext and/or AAD. + * It does not necessarily indicate a more serious error. + * There is no call to EVP_CipherFinal. + */ + ret = YACA_ERROR_INVALID_PARAMETER; + } else { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + } return ret; } @@ -1056,6 +1060,7 @@ int encrypt_finalize(yaca_context_h ctx, { struct yaca_encrypt_context_s *c = get_encrypt_context(ctx); int ret; + int mode; int loutput_len = 0; if (c == NULL || output == NULL || output_len == NULL || op_type != c->op_type) @@ -1064,10 +1069,19 @@ int encrypt_finalize(yaca_context_h ctx, if (!verify_state_change(c, STATE_FINALIZED)) return YACA_ERROR_INVALID_PARAMETER; - if (EVP_CIPHER_CTX_mode(c->cipher_ctx) != EVP_CIPH_WRAP_MODE) { + mode = EVP_CIPHER_CTX_mode(c->cipher_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) - return ERROR_HANDLE(); + if (ret != 1 || loutput_len < 0) { + if (mode == EVP_CIPH_GCM_MODE && op_type == OP_DECRYPT) + /* 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(); + } } *output_len = loutput_len; -- 2.7.4 From cbd593de08b1b87a0055fc89365a13ce97a1f2d2 Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Mon, 12 Sep 2016 10:30:53 +0900 Subject: [PATCH 13/16] Revert "Fix svace defects" This reverts commit 60428c2b10ccec13afe901d21b87ac949ffafa4c. 2 Svace defects (141053, 142079) is handled as `won't fix`, defended by assert() checking and logically Change-Id: I4d29b8e0c430929a57767293ec9c0d442e2f44e4 Signed-off-by: Kyungwook Tak --- src/encrypt.c | 3 +-- src/rsa.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/encrypt.c b/src/encrypt.c index d343efe..9bf4e74 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -556,8 +556,7 @@ static int encrypt_ctx_restore(struct yaca_encrypt_context_s *c) } key = key_get_simple(c->backup_ctx->sym_key); - if (key == NULL) - return YACA_ERROR_INVALID_PARAMETER; + assert(key != NULL); ret = encrypt_ctx_init(c, c->backup_ctx->cipher, key->bit_len); assert(ret != YACA_ERROR_INVALID_PARAMETER); diff --git a/src/rsa.c b/src/rsa.c index 334a383..436c3b9 100644 --- a/src/rsa.c +++ b/src/rsa.c @@ -78,8 +78,7 @@ static int encrypt_decrypt(yaca_padding_e padding, assert(lpadding != -1); lasym_key = key_get_evp(key); - if (lasym_key == NULL) - return YACA_ERROR_INVALID_PARAMETER; + assert(lasym_key != NULL); ret = EVP_PKEY_size(lasym_key->evp); if (ret <= 0) { -- 2.7.4 From 0dd2d096bce922d2b7fba3fb7ba08c103e8ca715 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Tue, 13 Sep 2016 13:03:16 +0200 Subject: [PATCH 14/16] Describe padding usage for sign/verify operations Change-Id: I4efa09f2a57c7fcd5f81124fc57bcbf890b484d4 --- api/yaca/yaca_sign.h | 11 +++++++++++ api/yaca/yaca_simple.h | 3 ++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/api/yaca/yaca_sign.h b/api/yaca/yaca_sign.h index 84aae2c..16bcfd1 100755 --- a/api/yaca/yaca_sign.h +++ b/api/yaca/yaca_sign.h @@ -44,6 +44,9 @@ extern "C" { * @remarks For verification use yaca_verify_initialize(), yaca_verify_update() and * yaca_verify_finalize() functions with matching public key. * + * @remarks For RSA operations the default padding used is #YACA_PADDING_PKCS1. It can be + * changed using yaca_context_set_property() with #YACA_PROPERTY_PADDING. + * * @remarks The @a ctx should be released using yaca_context_destroy() * * @param[out] ctx Newly created context @@ -63,6 +66,8 @@ extern "C" { * * @see #yaca_key_type_e * @see #yaca_digest_algorithm_e + * @see #yaca_padding_e + * @see yaca_context_set_property() * @see yaca_sign_update() * @see yaca_sign_finalize() * @see yaca_verify_initialize() @@ -202,6 +207,10 @@ int yaca_sign_finalize(yaca_context_h ctx, * * @since_tizen 3.0 * + * @remarks For RSA operations the default padding used is #YACA_PADDING_PKCS1. It can be + * changed using yaca_context_set_property() with #YACA_PROPERTY_PADDING. + * For verify to succeed it has to be set to the same value it was signed with. + * * @remarks The @a ctx should be released using yaca_context_destroy() * * @param[out] ctx Newly created context @@ -221,6 +230,8 @@ int yaca_sign_finalize(yaca_context_h ctx, * * @see #yaca_key_type_e * @see #yaca_digest_algorithm_e + * @see #yaca_padding_e + * @see yaca_context_set_property() * @see yaca_verify_update() * @see yaca_verify_finalize() * @see yaca_context_destroy() diff --git a/api/yaca/yaca_simple.h b/api/yaca/yaca_simple.h index a6d00ce..9adb8ca 100755 --- a/api/yaca/yaca_simple.h +++ b/api/yaca/yaca_simple.h @@ -25,7 +25,8 @@ * - All operations are single-shot (no streaming possible) * - Context is not used * - Only digest, signatures and symmetric ciphers are supported - * - Disabling PKCS#5 padding for ECB and CBC chaining is not supported + * - Disabling PKCS#7 padding for ECB and CBC chaining is not supported + * - Changing the default PKCS#1 padding for sign/verify is not supported * - GCM and CCM chaining is not supported * - RC2 effective key bits property is not supported * - All outputs are allocated by the library -- 2.7.4 From b3a6beafac3b820e16efedc3d029981b74cd078a Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Tue, 13 Sep 2016 10:14:31 +0200 Subject: [PATCH 15/16] Remove get_sign_property() functionality Change-Id: Iadecd8f919eff7a3aa6efe6f4cdc096b5539ace5 --- src/sign.c | 74 ++------------------------------------------------------------ 1 file changed, 2 insertions(+), 72 deletions(-) diff --git a/src/sign.c b/src/sign.c index ea9ce6f..4aba130 100644 --- a/src/sign.c +++ b/src/sign.c @@ -168,76 +168,6 @@ int set_sign_property(yaca_context_h ctx, return YACA_ERROR_NONE; } -int get_sign_property(const yaca_context_h ctx, - yaca_property_e property, - void **value, - size_t *value_len) -{ - int ret; - struct yaca_sign_context_s *c = get_sign_context(ctx); - EVP_PKEY *pkey; - EVP_PKEY_CTX *pctx; - int pad; - yaca_padding_e padding; - - if (c == NULL || value == NULL) - return YACA_ERROR_INVALID_PARAMETER; - - assert(c->md_ctx != NULL); - - pctx = EVP_MD_CTX_pkey_ctx(c->md_ctx); - if (pctx == NULL) - return YACA_ERROR_INTERNAL; - - /* this function only supports padding */ - if (property != YACA_PROPERTY_PADDING) - return YACA_ERROR_INVALID_PARAMETER; - - pkey = EVP_PKEY_CTX_get0_pkey(pctx); - if (pkey == NULL) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); - return ret; - } - - /* padding only works for RSA */ - if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA) - return YACA_ERROR_INVALID_PARAMETER; - - ret = EVP_PKEY_CTX_get_rsa_padding(pctx, &pad); - if (ret <= 0) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); - return ret; - } - - switch (pad) { - case RSA_X931_PADDING: - padding = YACA_PADDING_X931; - break; - case RSA_PKCS1_PADDING: - padding = YACA_PADDING_PKCS1; - break; - case RSA_PKCS1_PSS_PADDING: - padding = YACA_PADDING_PKCS1_PSS; - break; - default: - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(YACA_ERROR_INTERNAL); - return ret; - } - - ret = yaca_malloc(sizeof(yaca_padding_e), value); - if (ret != YACA_ERROR_NONE) - return ret; - - memcpy(*value, &padding, sizeof(yaca_padding_e)); - if (value_len != NULL) - *value_len = sizeof(yaca_padding_e); - - return YACA_ERROR_NONE; -} - API int yaca_sign_initialize(yaca_context_h *ctx, yaca_digest_algorithm_e algo, const yaca_key_h prv_key) @@ -268,7 +198,7 @@ API int yaca_sign_initialize(yaca_context_h *ctx, nc->ctx.context_destroy = destroy_sign_context; nc->ctx.get_output_length = get_sign_output_length; nc->ctx.set_property = set_sign_property; - nc->ctx.get_property = get_sign_property; + nc->ctx.get_property = NULL; ret = digest_get_algorithm(algo, &md); if (ret != YACA_ERROR_NONE) @@ -515,7 +445,7 @@ API int yaca_verify_initialize(yaca_context_h *ctx, nc->ctx.context_destroy = destroy_sign_context; nc->ctx.get_output_length = NULL; nc->ctx.set_property = set_sign_property; - nc->ctx.get_property = get_sign_property; + nc->ctx.get_property = NULL; ret = digest_get_algorithm(algo, &md); if (ret != YACA_ERROR_NONE) -- 2.7.4 From efad90f650cd388ee7ba2c2ac2cfc1934b9b1c03 Mon Sep 17 00:00:00 2001 From: Dongsun Lee Date: Fri, 23 Sep 2016 10:12:47 +0900 Subject: [PATCH 16/16] Fix TYPO for removing warning during doxygen generation Change-Id: I1a971b00b321a56e6ea59d03f3c51056494f16ab Signed-off-by: Dongsun Lee --- api/yaca/yaca_types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/yaca/yaca_types.h b/api/yaca/yaca_types.h index 0f0ae33..59674bc 100755 --- a/api/yaca/yaca_types.h +++ b/api/yaca/yaca_types.h @@ -676,7 +676,7 @@ typedef enum { /** * PKCS #1 v1.5 padding with an SSL-specific modification that denotes that the party * is SSL3 capable. It is used for rollback attack detection in SSLv3. If during decryption it - * turns out that both parties are using #YACA_PADDING_PKCS1_SSL23 (both are communicating + * turns out that both parties are using #YACA_PADDING_PKCS1_SSLV23 (both are communicating * using SSL2 and both are SSL3 capable) it is treated as a rollback attack and an error is * returned. Suitable for low-level RSA public_encrypt/private_decrypt operations. For * low-level operations the input must be at least 11 bytes shorter than the key length. -- 2.7.4