From 21379829e551a05db75f42a8daecf80279c9f73b Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Thu, 18 Aug 2016 11:16:02 +0200 Subject: [PATCH 01/16] Handle RSA padding errors Change-Id: Ie722ad2ba6c70b4a3ed799ffc8057e0610abc1d4 --- src/debug.c | 25 +++++++++++++++++++++++++ src/rsa.c | 3 +-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/debug.c b/src/debug.c index 0dbed34..33779b8 100644 --- a/src/debug.c +++ b/src/debug.c @@ -124,6 +124,7 @@ int error_handle(const char *file, int line, const char *function) /* known errors */ 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_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): @@ -163,6 +164,30 @@ int error_handle(const char *file, int line, const char *function) break; } + /* known rsa padding errors */ + if (ret == YACA_ERROR_NONE && ERR_GET_LIB(err) == ERR_LIB_RSA) { + switch (ERR_GET_FUNC(err)) { + case RSA_F_RSA_PADDING_CHECK_NONE: + case RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP: + case RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1: + case RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1: + case RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2: + case RSA_F_RSA_PADDING_CHECK_SSLV23: + case RSA_F_RSA_PADDING_CHECK_X931: + case RSA_F_RSA_PADDING_ADD_NONE: + case RSA_F_RSA_PADDING_ADD_PKCS1_OAEP: + case RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1: + case RSA_F_RSA_PADDING_ADD_PKCS1_PSS: + case RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1: + case RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1: + case RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2: + case RSA_F_RSA_PADDING_ADD_SSLV23: + case RSA_F_RSA_PADDING_ADD_X931: + ret = YACA_ERROR_INVALID_PARAMETER; + break; + } + } + /* fatal errors */ int reason = ERR_GET_REASON(err); if (ret == YACA_ERROR_NONE && reason <= GENERIC_REASON_MAX && ERR_FATAL_ERROR(err) > 0) { diff --git a/src/rsa.c b/src/rsa.c index 534ffe9..8d07f11 100644 --- a/src/rsa.c +++ b/src/rsa.c @@ -100,8 +100,7 @@ static int encrypt_decrypt(yaca_padding_e padding, lpadding); if (ret < 0) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); + ret = ERROR_HANDLE(); goto exit; } -- 2.7.4 From 5375f24f02a95cc049aebe78da395f77e5051062 Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Mon, 29 Aug 2016 16:19:44 +0200 Subject: [PATCH 02/16] Unify argument naming and description In digest, sign & simple API: - data -> message, - data_len -> message_len, - data to be verified -> message, - data to be signed -> message to be signed, - signature -> message signature to be verified (verify only) - NULL input allowed Change-Id: Ib8283fe13e44f1be261b90327f3034a626587d39 --- api/yaca/yaca_digest.h | 10 +++--- api/yaca/yaca_sign.h | 32 +++++++++--------- api/yaca/yaca_simple.h | 88 +++++++++++++++++++++++++++++--------------------- src/digest.c | 6 ++-- src/sign.c | 16 ++++----- 5 files changed, 83 insertions(+), 69 deletions(-) diff --git a/api/yaca/yaca_digest.h b/api/yaca/yaca_digest.h index b5dfaf2..d9d25cb 100755 --- a/api/yaca/yaca_digest.h +++ b/api/yaca/yaca_digest.h @@ -61,13 +61,13 @@ extern "C" { int yaca_digest_initialize(yaca_context_h *ctx, yaca_digest_algorithm_e algo); /** - * @brief Feeds the data into the message digest algorithm. + * @brief Feeds the message into the message digest algorithm. * * @since_tizen 3.0 * - * @param[in,out] ctx Context created by yaca_digest_initialize() - * @param[in] data Data from which the digest is to be calculated - * @param[in] data_len Length of the data + * @param[in,out] ctx Context created by yaca_digest_initialize() + * @param[in] message Message from which the digest is to be calculated + * @param[in] message_len Length of the message * * @return #YACA_ERROR_NONE on success, negative on error * @retval #YACA_ERROR_NONE Successful @@ -78,7 +78,7 @@ int yaca_digest_initialize(yaca_context_h *ctx, yaca_digest_algorithm_e algo); * @see yaca_digest_initialize() * @see yaca_digest_finalize() */ -int yaca_digest_update(yaca_context_h ctx, const char *data, size_t data_len); +int yaca_digest_update(yaca_context_h ctx, const char *message, size_t message_len); /** * @brief Calculates the final digest. diff --git a/api/yaca/yaca_sign.h b/api/yaca/yaca_sign.h index 8db0e1e..84aae2c 100755 --- a/api/yaca/yaca_sign.h +++ b/api/yaca/yaca_sign.h @@ -143,14 +143,14 @@ int yaca_sign_initialize_cmac(yaca_context_h *ctx, const yaca_key_h sym_key); /** - * @brief Feeds the data into the digital signature or MAC algorithm. + * @brief Feeds the message into the digital signature or MAC algorithm. * * @since_tizen 3.0 * - * @param[in,out] ctx Context created by yaca_sign_initialize(), - * yaca_sign_initialize_hmac() or yaca_sign_initialize_cmac() - * @param[in] data Data to be signed - * @param[in] data_len Length of the data + * @param[in,out] ctx Context created by yaca_sign_initialize(), + * yaca_sign_initialize_hmac() or yaca_sign_initialize_cmac() + * @param[in] message Message to be signed + * @param[in] message_len Length of the message * * @return #YACA_ERROR_NONE on success, negative on error * @retval #YACA_ERROR_NONE Successful @@ -164,8 +164,8 @@ int yaca_sign_initialize_cmac(yaca_context_h *ctx, * @see yaca_sign_initialize_cmac() */ int yaca_sign_update(yaca_context_h ctx, - const char *data, - size_t data_len); + const char *message, + size_t message_len); /** * @brief Calculates the final signature or MAC. @@ -176,7 +176,7 @@ int yaca_sign_update(yaca_context_h ctx, * signature or MAC of an empty message. * * @param[in,out] ctx A valid sign context - * @param[out] signature Buffer for the MAC or the signature + * @param[out] signature Buffer for the MAC or the message signature * (must be allocated by client, see yaca_context_get_output_length()) * @param[out] signature_len Length of the MAC or the signature, * actual number of bytes written will be returned here @@ -230,13 +230,13 @@ int yaca_verify_initialize(yaca_context_h *ctx, const yaca_key_h pub_key); /** - * @brief Feeds the data into the digital signature verification algorithm. + * @brief Feeds the message into the digital signature verification algorithm. * * @since_tizen 3.0 * - * @param[in,out] ctx Context created by yaca_verify_initialize() - * @param[in] data Data to be verified - * @param[in] data_len Length of the data + * @param[in,out] ctx Context created by yaca_verify_initialize() + * @param[in] message Message + * @param[in] message_len Length of the message * * @return #YACA_ERROR_NONE on success, negative on error * @retval #YACA_ERROR_NONE Successful @@ -248,8 +248,8 @@ int yaca_verify_initialize(yaca_context_h *ctx, * @see yaca_verify_finalize() */ int yaca_verify_update(yaca_context_h ctx, - const char *data, - size_t data_len); + const char *message, + size_t message_len); /** * @brief Performs the verification. @@ -260,8 +260,8 @@ int yaca_verify_update(yaca_context_h ctx, * the signature of an empty message. * * @param[in,out] ctx A valid verify context - * @param[in] signature Input signature (returned by yaca_sign_finalize()) - * @param[in] signature_len Size of the signature + * @param[in] signature Message signature to be verified + * @param[in] signature_len Length of the signature * * @return #YACA_ERROR_NONE on success, negative on error * @retval #YACA_ERROR_NONE Successful diff --git a/api/yaca/yaca_simple.h b/api/yaca/yaca_simple.h index adb4456..a6d00ce 100755 --- a/api/yaca/yaca_simple.h +++ b/api/yaca/yaca_simple.h @@ -55,6 +55,8 @@ extern "C" { * * @remarks The @a ciphertext should be freed using yaca_free() * + * @remarks The @a plaintext can be NULL but then @a plaintext_len must be 0 + * * @param[in] algo Encryption algorithm (select #YACA_ENCRYPT_AES if unsure) * @param[in] bcm Chaining mode (select #YACA_BCM_CBC if unsure) * @param[in] sym_key Symmetric encryption key (see yaca_key.h for key generation functions) @@ -94,6 +96,8 @@ int yaca_simple_encrypt(yaca_encrypt_algorithm_e algo, * * @remarks The @a plaintext should be freed using yaca_free() * + * @remarks The @a ciphertext can be NULL but then @a ciphertext_len must be 0 + * * @param[in] algo Decryption algorithm that was used to encrypt the data * @param[in] bcm Chaining mode that was used to encrypt the data * @param[in] sym_key Symmetric encryption key that was used to encrypt the data @@ -125,17 +129,19 @@ int yaca_simple_decrypt(yaca_encrypt_algorithm_e algo, size_t *plaintext_len); /** - * @brief Calculates a digest of a buffer. + * @brief Calculates a digest of a message. * * @since_tizen 3.0 * * @remarks The @a digest should be freed using yaca_free() * - * @param[in] algo Digest algorithm (select #YACA_DIGEST_SHA256 if unsure) - * @param[in] data Data from which the digest is to be calculated - * @param[in] data_len Length of the data. Can be 0. - * @param[out] digest Message digest, will be allocated by the library - * @param[out] digest_len Length of message digest (depends on algorithm) + * @remarks The @a message can be NULL but then @a message_len must be 0 + * + * @param[in] algo Digest algorithm (select #YACA_DIGEST_SHA256 if unsure) + * @param[in] message Message from which the digest is to be calculated + * @param[in] message_len Length of the message + * @param[out] digest Message digest, will be allocated by the library + * @param[out] digest_len Length of message digest (depends on algorithm) * * @return #YACA_ERROR_NONE on success, negative on error * @retval #YACA_ERROR_NONE Successful @@ -148,8 +154,8 @@ int yaca_simple_decrypt(yaca_encrypt_algorithm_e algo, * @see yaca_free() */ int yaca_simple_calculate_digest(yaca_digest_algorithm_e algo, - const char *data, - size_t data_len, + const char *message, + size_t message_len, char **digest, size_t *digest_len); @@ -160,14 +166,16 @@ int yaca_simple_calculate_digest(yaca_digest_algorithm_e algo, * * @remarks The @a signature should be freed using yaca_free() * + * @remarks The @a message can be NULL but then @a message_len must be 0 + * * @param[in] algo Digest algorithm that will be used * @param[in] prv_key Private key that will be used, algorithm is * deduced based on key type, supported key types: * - #YACA_KEY_TYPE_RSA_PRIV, * - #YACA_KEY_TYPE_DSA_PRIV, * - #YACA_KEY_TYPE_EC_PRIV - * @param[in] data Data to be signed - * @param[in] data_len Length of the data + * @param[in] message Message to be signed + * @param[in] message_len Length of the message * @param[out] signature Message signature, will be allocated by the library * @param[out] signature_len Length of the signature * @@ -185,8 +193,8 @@ int yaca_simple_calculate_digest(yaca_digest_algorithm_e algo, */ int yaca_simple_calculate_signature(yaca_digest_algorithm_e algo, const yaca_key_h prv_key, - const char *data, - size_t data_len, + const char *message, + size_t message_len, char **signature, size_t *signature_len); @@ -195,15 +203,17 @@ int yaca_simple_calculate_signature(yaca_digest_algorithm_e algo, * * @since_tizen 3.0 * + * @remarks The @a message can be NULL but then @a message_len must be 0 + * * @param[in] algo Digest algorithm that will be used * @param[in] pub_key Public key that will be used, algorithm is * deduced based on key type, supported key types: * - #YACA_KEY_TYPE_RSA_PUB, * - #YACA_KEY_TYPE_DSA_PUB, * - #YACA_KEY_TYPE_EC_PUB - * @param[in] data Signed data - * @param[in] data_len Length of the data - * @param[in] signature Message signature + * @param[in] message Message + * @param[in] message_len Length of the message + * @param[in] signature Message signature to be verified * @param[in] signature_len Length of the signature * * @return #YACA_ERROR_NONE on success, negative on error @@ -220,8 +230,8 @@ int yaca_simple_calculate_signature(yaca_digest_algorithm_e algo, */ int yaca_simple_verify_signature(yaca_digest_algorithm_e algo, const yaca_key_h pub_key, - const char *data, - size_t data_len, + const char *message, + size_t message_len, const char *signature, size_t signature_len); @@ -235,14 +245,16 @@ int yaca_simple_verify_signature(yaca_digest_algorithm_e algo, * * @remarks The @a mac should be freed using yaca_free() * - * @param[in] algo Digest algorithm that will be used - * @param[in] sym_key Key that will be used, supported key types: - * - #YACA_KEY_TYPE_SYMMETRIC, - * - #YACA_KEY_TYPE_DES - * @param[in] data Data to calculate HMAC from - * @param[in] data_len Length of the data - * @param[out] mac MAC, will be allocated by the library - * @param[out] mac_len Length of the MAC + * @remarks The @a message can be NULL but then @a message_len must be 0 + * + * @param[in] algo Digest algorithm that will be used + * @param[in] sym_key Key that will be used, supported key types: + * - #YACA_KEY_TYPE_SYMMETRIC, + * - #YACA_KEY_TYPE_DES + * @param[in] message Message to calculate HMAC from + * @param[in] message_len Length of the message + * @param[out] mac MAC, will be allocated by the library + * @param[out] mac_len Length of the MAC * * @return #YACA_ERROR_NONE on success, negative on error * @retval #YACA_ERROR_NONE Successful @@ -258,8 +270,8 @@ int yaca_simple_verify_signature(yaca_digest_algorithm_e algo, */ int yaca_simple_calculate_hmac(yaca_digest_algorithm_e algo, const yaca_key_h sym_key, - const char *data, - size_t data_len, + const char *message, + size_t message_len, char **mac, size_t *mac_len); @@ -273,14 +285,16 @@ int yaca_simple_calculate_hmac(yaca_digest_algorithm_e algo, * * @remarks The @a mac should be freed using yaca_free() * - * @param[in] algo Encryption algorithm that will be used - * @param[in] sym_key Key that will be used, supported key types: - * - #YACA_KEY_TYPE_SYMMETRIC, - * - #YACA_KEY_TYPE_DES - * @param[in] data Data to calculate CMAC from - * @param[in] data_len Length of the data - * @param[out] mac MAC, will be allocated by the library - * @param[out] mac_len Length of the MAC + * @remarks The @a message can be NULL but then @a message_len must be 0 + * + * @param[in] algo Encryption algorithm that will be used + * @param[in] sym_key Key that will be used, supported key types: + * - #YACA_KEY_TYPE_SYMMETRIC, + * - #YACA_KEY_TYPE_DES + * @param[in] message Message to calculate CMAC from + * @param[in] message_len Length of the message + * @param[out] mac MAC, will be allocated by the library + * @param[out] mac_len Length of the MAC * * @return #YACA_ERROR_NONE on success, negative on error * @retval #YACA_ERROR_NONE Successful @@ -296,8 +310,8 @@ int yaca_simple_calculate_hmac(yaca_digest_algorithm_e algo, */ int yaca_simple_calculate_cmac(yaca_encrypt_algorithm_e algo, const yaca_key_h sym_key, - const char *data, - size_t data_len, + const char *message, + size_t message_len, char **mac, size_t *mac_len); diff --git a/src/digest.c b/src/digest.c index 0d7b426..361b9f8 100644 --- a/src/digest.c +++ b/src/digest.c @@ -165,15 +165,15 @@ exit: return ret; } -API int yaca_digest_update(yaca_context_h ctx, const char *data, size_t data_len) +API int yaca_digest_update(yaca_context_h ctx, const char *message, size_t message_len) { struct yaca_digest_context_s *c = get_digest_context(ctx); int ret; - if (c == NULL || data == NULL || data_len == 0) + if (c == NULL || message == NULL || message_len == 0) return YACA_ERROR_INVALID_PARAMETER; - ret = EVP_DigestUpdate(c->md_ctx, data, data_len); + ret = EVP_DigestUpdate(c->md_ctx, message, message_len); if (ret != 1) { ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); diff --git a/src/sign.c b/src/sign.c index f79e227..aaa5863 100644 --- a/src/sign.c +++ b/src/sign.c @@ -442,17 +442,17 @@ exit: } API int yaca_sign_update(yaca_context_h ctx, - const char *data, - size_t data_len) + const char *message, + size_t message_len) { struct yaca_sign_context_s *c = get_sign_context(ctx); int ret; if (c == NULL || c->op_type != OP_SIGN || - data == NULL || data_len == 0) + message == NULL || message_len == 0) return YACA_ERROR_INVALID_PARAMETER; - ret = EVP_DigestSignUpdate(c->md_ctx, data, data_len); + ret = EVP_DigestSignUpdate(c->md_ctx, message, message_len); if (ret != 1) { ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); @@ -544,16 +544,16 @@ exit: } API int yaca_verify_update(yaca_context_h ctx, - const char *data, - size_t data_len) + const char *message, + size_t message_len) { struct yaca_sign_context_s *c = get_sign_context(ctx); int ret; - if (c == NULL || data == NULL || data_len == 0 || c->op_type != OP_VERIFY) + if (c == NULL || message == NULL || message_len == 0 || c->op_type != OP_VERIFY) return YACA_ERROR_INVALID_PARAMETER; - ret = EVP_DigestVerifyUpdate(c->md_ctx, data, data_len); + ret = EVP_DigestVerifyUpdate(c->md_ctx, message, message_len); if (ret != 1) { ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); -- 2.7.4 From c068acd76aca55c9117a6a6203267111f69022d0 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Mon, 29 Aug 2016 13:45:18 +0200 Subject: [PATCH 03/16] s/INTERNAL_KEYLEN/KEYLEN_COMPONENT/ in the "private" keylen defines Change-Id: I990e569bdb85a862d7aca98b2afa114adb6f383c --- api/yaca/yaca_types.h | 74 +++++++++++++++++++++++++-------------------------- src/key.c | 16 +++++------ 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/api/yaca/yaca_types.h b/api/yaca/yaca_types.h index bdd7f9e..91e3d84 100755 --- a/api/yaca/yaca_types.h +++ b/api/yaca/yaca_types.h @@ -99,40 +99,40 @@ extern "C" { /** @cond Don't include those defines in doxygen, they are not to be used directly */ /* types */ -#define YACA_INTERNAL_KEYLEN_TYPE_MASK (0xF << 28) -#define YACA_INTERNAL_KEYLEN_TYPE_BITS (0U << 28) -#define YACA_INTERNAL_KEYLEN_TYPE_DH (1U << 28) -#define YACA_INTERNAL_KEYLEN_TYPE_DH_RFC (2U << 28) -#define YACA_INTERNAL_KEYLEN_TYPE_EC (3U << 28) +#define YACA_KEYLEN_COMPONENT_TYPE_MASK (0xF << 28) +#define YACA_KEYLEN_COMPONENT_TYPE_BITS (0U << 28) +#define YACA_KEYLEN_COMPONENT_TYPE_DH (1U << 28) +#define YACA_KEYLEN_COMPONENT_TYPE_DH_RFC (2U << 28) +#define YACA_KEYLEN_COMPONENT_TYPE_EC (3U << 28) /* DH type */ -#define YACA_INTERNAL_KEYLEN_DH_GEN_MASK (0xF << 24) -#define YACA_INTERNAL_KEYLEN_DH_GEN_2 (0U << 24) -#define YACA_INTERNAL_KEYLEN_DH_GEN_5 (1U << 24) +#define YACA_KEYLEN_COMPONENT_DH_GEN_MASK (0xF << 24) +#define YACA_KEYLEN_COMPONENT_DH_GEN_2 (0U << 24) +#define YACA_KEYLEN_COMPONENT_DH_GEN_5 (1U << 24) -#define YACA_INTERNAL_KEYLEN_DH_PRIME_MASK (0xFFFF << 0) +#define YACA_KEYLEN_COMPONENT_DH_PRIME_MASK (0xFFFF << 0) /* DH_RFC type */ -#define YACA_INTERNAL_KEYLEN_DH_RFC_MASK (0xF << 24) -#define YACA_INTERNAL_KEYLEN_DH_RFC_160 (0U << 24) -#define YACA_INTERNAL_KEYLEN_DH_RFC_224 (1U << 24) -#define YACA_INTERNAL_KEYLEN_DH_RFC_256 (2U << 24) +#define YACA_KEYLEN_COMPONENT_DH_RFC_MASK (0xF << 24) +#define YACA_KEYLEN_COMPONENT_DH_RFC_160 (0U << 24) +#define YACA_KEYLEN_COMPONENT_DH_RFC_224 (1U << 24) +#define YACA_KEYLEN_COMPONENT_DH_RFC_256 (2U << 24) /* EC type */ -#define YACA_INTERNAL_KEYLEN_EC_PRIME (0U << 24) -#define YACA_INTERNAL_KEYLEN_EC_SECP (1U << 24) -#define YACA_INTERNAL_KEYLEN_EC_SECT (2U << 24) -#define YACA_INTERNAL_KEYLEN_EC_BRAINPOOL (3U << 24) - -#define YACA_INTERNAL_KEYLEN_EC_V (0U << 20) -#define YACA_INTERNAL_KEYLEN_EC_R (1U << 20) -#define YACA_INTERNAL_KEYLEN_EC_K (2U << 20) -#define YACA_INTERNAL_KEYLEN_EC_T (3U << 20) - -#define YACA_INTERNAL_KEYLEN_EC_1 (0U << 16) -#define YACA_INTERNAL_KEYLEN_EC_2 (1U << 16) -#define YACA_INTERNAL_KEYLEN_EC_3 (2U << 16) -#define YACA_INTERNAL_KEYLEN_EC_4 (3U << 16) +#define YACA_KEYLEN_COMPONENT_EC_PRIME (0U << 24) +#define YACA_KEYLEN_COMPONENT_EC_SECP (1U << 24) +#define YACA_KEYLEN_COMPONENT_EC_SECT (2U << 24) +#define YACA_KEYLEN_COMPONENT_EC_BRAINPOOL (3U << 24) + +#define YACA_KEYLEN_COMPONENT_EC_V (0U << 20) +#define YACA_KEYLEN_COMPONENT_EC_R (1U << 20) +#define YACA_KEYLEN_COMPONENT_EC_K (2U << 20) +#define YACA_KEYLEN_COMPONENT_EC_T (3U << 20) + +#define YACA_KEYLEN_COMPONENT_EC_1 (0U << 16) +#define YACA_KEYLEN_COMPONENT_EC_2 (1U << 16) +#define YACA_KEYLEN_COMPONENT_EC_3 (2U << 16) +#define YACA_KEYLEN_COMPONENT_EC_4 (3U << 16) /** @endcond */ /** @@ -265,15 +265,15 @@ typedef enum { */ typedef enum { /** Elliptic curve prime192v1 */ - YACA_KEY_LENGTH_EC_PRIME192V1 = YACA_INTERNAL_KEYLEN_TYPE_EC | YACA_INTERNAL_KEYLEN_EC_PRIME | YACA_INTERNAL_KEYLEN_EC_V | YACA_INTERNAL_KEYLEN_EC_1 | 192U, + YACA_KEY_LENGTH_EC_PRIME192V1 = YACA_KEYLEN_COMPONENT_TYPE_EC | YACA_KEYLEN_COMPONENT_EC_PRIME | YACA_KEYLEN_COMPONENT_EC_V | YACA_KEYLEN_COMPONENT_EC_1 | 192U, /** Elliptic curve prime256v1 */ - YACA_KEY_LENGTH_EC_PRIME256V1 = YACA_INTERNAL_KEYLEN_TYPE_EC | YACA_INTERNAL_KEYLEN_EC_PRIME | YACA_INTERNAL_KEYLEN_EC_V | YACA_INTERNAL_KEYLEN_EC_1 | 256U, + YACA_KEY_LENGTH_EC_PRIME256V1 = YACA_KEYLEN_COMPONENT_TYPE_EC | YACA_KEYLEN_COMPONENT_EC_PRIME | YACA_KEYLEN_COMPONENT_EC_V | YACA_KEYLEN_COMPONENT_EC_1 | 256U, /** Elliptic curve secp256k1 */ - YACA_KEY_LENGTH_EC_SECP256K1 = YACA_INTERNAL_KEYLEN_TYPE_EC | YACA_INTERNAL_KEYLEN_EC_SECP | YACA_INTERNAL_KEYLEN_EC_K | YACA_INTERNAL_KEYLEN_EC_1 | 256U, + YACA_KEY_LENGTH_EC_SECP256K1 = YACA_KEYLEN_COMPONENT_TYPE_EC | YACA_KEYLEN_COMPONENT_EC_SECP | YACA_KEYLEN_COMPONENT_EC_K | YACA_KEYLEN_COMPONENT_EC_1 | 256U, /** Elliptic curve secp384r1 */ - YACA_KEY_LENGTH_EC_SECP384R1 = YACA_INTERNAL_KEYLEN_TYPE_EC | YACA_INTERNAL_KEYLEN_EC_SECP | YACA_INTERNAL_KEYLEN_EC_R | YACA_INTERNAL_KEYLEN_EC_1 | 384U, + YACA_KEY_LENGTH_EC_SECP384R1 = YACA_KEYLEN_COMPONENT_TYPE_EC | YACA_KEYLEN_COMPONENT_EC_SECP | YACA_KEYLEN_COMPONENT_EC_R | YACA_KEYLEN_COMPONENT_EC_1 | 384U, /** Elliptic curve secp521r1 */ - YACA_KEY_LENGTH_EC_SECP521R1 = YACA_INTERNAL_KEYLEN_TYPE_EC | YACA_INTERNAL_KEYLEN_EC_SECP | YACA_INTERNAL_KEYLEN_EC_R | YACA_INTERNAL_KEYLEN_EC_1 | 521U + YACA_KEY_LENGTH_EC_SECP521R1 = YACA_KEYLEN_COMPONENT_TYPE_EC | YACA_KEYLEN_COMPONENT_EC_SECP | YACA_KEYLEN_COMPONENT_EC_R | YACA_KEYLEN_COMPONENT_EC_1 | 521U } yaca_key_bit_length_ec_e; /** @@ -281,13 +281,13 @@ typedef enum { * To be or'ed with safe prime length in bits. Prime length is recommended * to be 2048 bits or higher. */ -#define YACA_KEY_LENGTH_DH_GENERATOR_2 (YACA_INTERNAL_KEYLEN_TYPE_DH | YACA_INTERNAL_KEYLEN_DH_GEN_2) +#define YACA_KEY_LENGTH_DH_GENERATOR_2 (YACA_KEYLEN_COMPONENT_TYPE_DH | YACA_KEYLEN_COMPONENT_DH_GEN_2) /** * @brief A value indicating generator equal 5 for DH parameters. * To be or'ed with safe prime length in bits. Prime length is recommended * to be 2048 bits or higher. */ -#define YACA_KEY_LENGTH_DH_GENERATOR_5 (YACA_INTERNAL_KEYLEN_TYPE_DH | YACA_INTERNAL_KEYLEN_DH_GEN_5) +#define YACA_KEY_LENGTH_DH_GENERATOR_5 (YACA_KEYLEN_COMPONENT_TYPE_DH | YACA_KEYLEN_COMPONENT_DH_GEN_5) /** * @brief Enumeration of YACA DH parameters taken from RFC 5114. @@ -299,11 +299,11 @@ typedef enum { */ typedef enum { /** RFC 5114 DH parameters 1024_160 */ - YACA_KEY_LENGTH_DH_RFC_1024_160 = YACA_INTERNAL_KEYLEN_TYPE_DH_RFC | YACA_INTERNAL_KEYLEN_DH_RFC_160 | 1024U, + YACA_KEY_LENGTH_DH_RFC_1024_160 = YACA_KEYLEN_COMPONENT_TYPE_DH_RFC | YACA_KEYLEN_COMPONENT_DH_RFC_160 | 1024U, /** RFC 5114 DH parameters 2048_224 */ - YACA_KEY_LENGTH_DH_RFC_2048_224 = YACA_INTERNAL_KEYLEN_TYPE_DH_RFC | YACA_INTERNAL_KEYLEN_DH_RFC_224 | 2048U, + YACA_KEY_LENGTH_DH_RFC_2048_224 = YACA_KEYLEN_COMPONENT_TYPE_DH_RFC | YACA_KEYLEN_COMPONENT_DH_RFC_224 | 2048U, /** RFC 5114 DH parameters 2048_256 */ - YACA_KEY_LENGTH_DH_RFC_2048_256 = YACA_INTERNAL_KEYLEN_TYPE_DH_RFC | YACA_INTERNAL_KEYLEN_DH_RFC_256 | 2048U + YACA_KEY_LENGTH_DH_RFC_2048_256 = YACA_KEYLEN_COMPONENT_TYPE_DH_RFC | YACA_KEYLEN_COMPONENT_DH_RFC_256 | 2048U } yaca_key_bit_length_dh_rfc_e; /** diff --git a/src/key.c b/src/key.c index 35ca37e..aeaf7a9 100644 --- a/src/key.c +++ b/src/key.c @@ -1025,7 +1025,7 @@ static int generate_evp_pkey_params(int evp_id, size_t key_bit_len, EVP_PKEY **p switch (evp_id) { case EVP_PKEY_DSA: - if ((key_bit_len & YACA_INTERNAL_KEYLEN_TYPE_MASK) != YACA_INTERNAL_KEYLEN_TYPE_BITS || + if ((key_bit_len & YACA_KEYLEN_COMPONENT_TYPE_MASK) != YACA_KEYLEN_COMPONENT_TYPE_BITS || key_bit_len > INT_MAX || key_bit_len < 512 || key_bit_len % 64 != 0) return YACA_ERROR_INVALID_PARAMETER; @@ -1033,9 +1033,9 @@ static int generate_evp_pkey_params(int evp_id, size_t key_bit_len, EVP_PKEY **p break; case EVP_PKEY_DH: - if ((key_bit_len & YACA_INTERNAL_KEYLEN_TYPE_MASK) == YACA_INTERNAL_KEYLEN_TYPE_DH) { - size_t gen_block = key_bit_len & YACA_INTERNAL_KEYLEN_DH_GEN_MASK; - size_t prime_len_block = key_bit_len & YACA_INTERNAL_KEYLEN_DH_PRIME_MASK; + if ((key_bit_len & YACA_KEYLEN_COMPONENT_TYPE_MASK) == YACA_KEYLEN_COMPONENT_TYPE_DH) { + 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 */ @@ -1043,14 +1043,14 @@ static int generate_evp_pkey_params(int evp_id, size_t key_bit_len, EVP_PKEY **p return YACA_ERROR_INVALID_PARAMETER; dh_prime_len = prime_len_block; - if (gen_block == YACA_INTERNAL_KEYLEN_DH_GEN_2) + if (gen_block == YACA_KEYLEN_COMPONENT_DH_GEN_2) dh_generator = 2; - else if (gen_block == YACA_INTERNAL_KEYLEN_DH_GEN_5) + else if (gen_block == YACA_KEYLEN_COMPONENT_DH_GEN_5) dh_generator = 5; else return YACA_ERROR_INVALID_PARAMETER; - } else if ((key_bit_len & YACA_INTERNAL_KEYLEN_TYPE_MASK) == YACA_INTERNAL_KEYLEN_TYPE_DH_RFC) { + } else if ((key_bit_len & YACA_KEYLEN_COMPONENT_TYPE_MASK) == YACA_KEYLEN_COMPONENT_TYPE_DH_RFC) { if (key_bit_len == YACA_KEY_LENGTH_DH_RFC_1024_160) dh_rfc5114 = 1; /* OpenSSL magic numbers */ else if (key_bit_len == YACA_KEY_LENGTH_DH_RFC_2048_224) @@ -1179,7 +1179,7 @@ static int generate_evp_pkey_key(int evp_id, size_t key_bit_len, EVP_PKEY *param } if (evp_id == EVP_PKEY_RSA) { - if ((key_bit_len & YACA_INTERNAL_KEYLEN_TYPE_MASK) != YACA_INTERNAL_KEYLEN_TYPE_BITS || + if ((key_bit_len & YACA_KEYLEN_COMPONENT_TYPE_MASK) != YACA_KEYLEN_COMPONENT_TYPE_BITS || key_bit_len > INT_MAX || key_bit_len % 8 != 0) { ret = YACA_ERROR_INVALID_PARAMETER; goto exit; -- 2.7.4 From 918f0cfc1e60eb672bca2e8a4ad6ae819fb3ccc9 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Thu, 25 Aug 2016 14:05:56 +0200 Subject: [PATCH 04/16] Fix yaca_sign_initialize_hmac/cmac memory leak. Fix sign example indentation. Change-Id: I65664d815ebff5eb5861d24a649ea94c9910915f --- examples/sign.c | 60 ++++++++++++++++++++++++++++----------------------------- src/sign.c | 4 ---- 2 files changed, 30 insertions(+), 34 deletions(-) diff --git a/examples/sign.c b/examples/sign.c index df7ff58..db6f39a 100644 --- a/examples/sign.c +++ b/examples/sign.c @@ -50,22 +50,22 @@ void simple_sign_verify_asym(yaca_key_type_e type, const char *algo) /* SIGN */ if (yaca_simple_calculate_signature(YACA_DIGEST_SHA512, - prv, - lorem4096, - LOREM4096_SIZE, - &signature, - &signature_len) != YACA_ERROR_NONE) + prv, + lorem4096, + LOREM4096_SIZE, + &signature, + &signature_len) != YACA_ERROR_NONE) goto exit; dump_hex(signature, signature_len, "[Simple API] %s Signature of lorem4096:", algo); /* VERIFY */ if (yaca_simple_verify_signature(YACA_DIGEST_SHA512, - pub, - lorem4096, - LOREM4096_SIZE, - signature, - signature_len) != YACA_ERROR_NONE) + pub, + lorem4096, + LOREM4096_SIZE, + signature, + signature_len) != YACA_ERROR_NONE) printf("[Simple API] %s verification failed\n", algo); else printf("[Simple API] %s verification successful\n", algo); @@ -90,22 +90,22 @@ void simple_sign_verify_hmac(void) /* SIGN */ if (yaca_simple_calculate_hmac(YACA_DIGEST_SHA512, - key, - lorem4096, - LOREM4096_SIZE, - &signature1, - &signature_len) != YACA_ERROR_NONE) + key, + lorem4096, + LOREM4096_SIZE, + &signature1, + &signature_len) != YACA_ERROR_NONE) goto exit; dump_hex(signature1, signature_len, "[Simple API] HMAC Signature of lorem4096:"); /* VERIFY */ if (yaca_simple_calculate_hmac(YACA_DIGEST_SHA512, - key, - lorem4096, - LOREM4096_SIZE, - &signature2, - &signature_len) != YACA_ERROR_NONE) + key, + lorem4096, + LOREM4096_SIZE, + &signature2, + &signature_len) != YACA_ERROR_NONE) goto exit; if (yaca_memcmp(signature1, signature2, signature_len) != YACA_ERROR_NONE) @@ -133,11 +133,11 @@ void simple_sign_verify_cmac(void) /* SIGN */ if (yaca_simple_calculate_cmac(YACA_ENCRYPT_AES, - key, - lorem4096, - LOREM4096_SIZE, - &signature1, - &signature_len) != YACA_ERROR_NONE) + key, + lorem4096, + LOREM4096_SIZE, + &signature1, + &signature_len) != YACA_ERROR_NONE) goto exit; dump_hex(signature1, signature_len, "[Simple API] CMAC Signature of lorem4096:"); @@ -145,11 +145,11 @@ void simple_sign_verify_cmac(void) /* VERIFY */ if (yaca_simple_calculate_cmac(YACA_ENCRYPT_AES, - key, - lorem4096, - LOREM4096_SIZE, - &signature2, - &signature_len) != YACA_ERROR_NONE) + key, + lorem4096, + LOREM4096_SIZE, + &signature2, + &signature_len) != YACA_ERROR_NONE) goto exit; if (yaca_memcmp(signature1, signature2, signature_len) != YACA_ERROR_NONE) diff --git a/src/sign.c b/src/sign.c index aaa5863..79d7759 100644 --- a/src/sign.c +++ b/src/sign.c @@ -343,8 +343,6 @@ API int yaca_sign_initialize_hmac(yaca_context_h *ctx, goto exit; } - pkey = NULL; - *ctx = (yaca_context_h)nc; nc = NULL; ret = YACA_ERROR_NONE; @@ -427,8 +425,6 @@ API int yaca_sign_initialize_cmac(yaca_context_h *ctx, goto exit; } - pkey = NULL; - *ctx = (yaca_context_h)nc; nc = NULL; ret = YACA_ERROR_NONE; -- 2.7.4 From f0db15fd838fde8ed300ea6cce0992cc44655624 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Fri, 26 Aug 2016 16:35:24 +0200 Subject: [PATCH 05/16] Fix: Always use yaca_cleanup() before exit. Change-Id: Ie82636d54df5acd3397917d9bec07d530f662a05 --- examples/key_gen.c | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/key_gen.c b/examples/key_gen.c index a1ddf36..a771d81 100644 --- a/examples/key_gen.c +++ b/examples/key_gen.c @@ -115,6 +115,7 @@ int main() yaca_key_destroy(key); yaca_key_destroy(key_params); + yaca_cleanup(); return 0; error: -- 2.7.4 From 73cbb13ec5a81e204ed68955b2e63f27b03615cd Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Tue, 23 Aug 2016 17:13:27 +0200 Subject: [PATCH 06/16] Fix symmetric key handling in seal/open. - generate DES key if algorithm is DES, - use sym_key_bit_len instead of default key length. Change-Id: Iab6b16af5e60e932aee1d807cf1edc94c99cffbb --- api/yaca/yaca_seal.h | 2 ++ src/seal.c | 28 +++++++++++----------------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/api/yaca/yaca_seal.h b/api/yaca/yaca_seal.h index 97f8544..ac7da5c 100755 --- a/api/yaca/yaca_seal.h +++ b/api/yaca/yaca_seal.h @@ -53,6 +53,8 @@ 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 should be released using yaca_key_destroy() * * @remarks The @a iv should be released using yaca_key_destroy() diff --git a/src/seal.c b/src/seal.c index 83094ce..f9b16a4 100644 --- a/src/seal.c +++ b/src/seal.c @@ -34,23 +34,18 @@ #include "internal.h" -static int seal_generate_sym_key(const EVP_CIPHER *cipher, yaca_key_h *sym_key) +static int seal_generate_sym_key(yaca_encrypt_algorithm_e algo, + size_t sym_key_bit_len, + yaca_key_h *sym_key) { - int ret; - int key_len; - assert(sym_key != NULL); - assert(cipher != NULL); - - ret = EVP_CIPHER_key_length(cipher); - if (ret <= 0) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); - return ret; - } - key_len = ret; - return yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, key_len * 8, sym_key); + if (algo == YACA_ENCRYPT_3DES_3TDEA || + algo == YACA_ENCRYPT_UNSAFE_3DES_2TDEA || + algo == YACA_ENCRYPT_UNSAFE_DES) + return yaca_key_generate(YACA_KEY_TYPE_DES, sym_key_bit_len, sym_key); + else + return yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, sym_key_bit_len, sym_key); } static int seal_generate_iv(const EVP_CIPHER *cipher, yaca_key_h *iv) @@ -127,8 +122,7 @@ static int seal_encrypt_decrypt_key(const yaca_key_h asym_key, lasym_key->evp); if (ret <= 0) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); + ret = ERROR_HANDLE(); goto exit; } @@ -170,7 +164,7 @@ API int yaca_seal_initialize(yaca_context_h *ctx, if (ret != YACA_ERROR_NONE) goto exit; - ret = seal_generate_sym_key(cipher, &lsym_key); + ret = seal_generate_sym_key(algo, sym_key_bit_len, &lsym_key); if (ret != YACA_ERROR_NONE) goto exit; -- 2.7.4 From 168b5dce51bcb39f5dc98d95a32376c26b7080b4 Mon Sep 17 00:00:00 2001 From: Dongsun Lee Date: Tue, 30 Aug 2016 17:58:05 +0900 Subject: [PATCH 07/16] Fix TYPO:parammeters Change-Id: Iee2e8ab019ce5412ad6f7b230a065d553db19847 Signed-off-by: Dongsun Lee --- api/yaca/yaca_key.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/yaca/yaca_key.h b/api/yaca/yaca_key.h index 6f9a0f1..82ef7b9 100755 --- a/api/yaca/yaca_key.h +++ b/api/yaca/yaca_key.h @@ -68,7 +68,7 @@ int yaca_key_get_type(const yaca_key_h key, yaca_key_type_e *key_type); * asymmetric key (including key generation parameters). * * @remarks For Diffie-Helmann @a key_bit_len returns prime length in bits. Values - * used to generate the key/parammeters in yaca_key_generate() are not + * used to generate the key/parameters in yaca_key_generate() are not * restored. Neither generator number nor values from #yaca_key_bit_length_dh_rfc_e. * * @remarks For Elliptic Curves @a key_bit_len returns values from #yaca_key_bit_length_ec_e. -- 2.7.4 From e32e9176bc0e86f69cda37e0b02a2a652391cf28 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Wed, 24 Aug 2016 17:20:43 +0200 Subject: [PATCH 08/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 09/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 10/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 11/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 12/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 13/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 14/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 15/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 16/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