From 41ec80e72479f5a51865340b2959a6177766257a Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Wed, 6 Apr 2016 14:32:14 +0200 Subject: [PATCH 01/16] Some minor digest changes. - code style to make it more similar to the recent key changes - digest_ctx_free() Change-Id: Icf11abc94fb4811edfb6a9350905aed7f29e8e78 --- src/crypto.c | 2 +- src/ctx_p.h | 1 + src/digest.c | 71 ++++++++++++++++++++++++++++++++++++++++-------------------- 3 files changed, 49 insertions(+), 25 deletions(-) diff --git a/src/crypto.c b/src/crypto.c index 0b43bd6..dd24974 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -96,8 +96,8 @@ API int yaca_ctx_get_param(const yaca_ctx_h ctx, yaca_ex_param_e param, API void yaca_ctx_free(yaca_ctx_h ctx) { + ctx->ctx_destroy(ctx); yaca_free(ctx); - /* TODO: What about digest context? This should free specific contexts as well. */ } API int yaca_get_output_length(const yaca_ctx_h ctx, size_t input_len) diff --git a/src/ctx_p.h b/src/ctx_p.h index cdd9e51..c8da49e 100644 --- a/src/ctx_p.h +++ b/src/ctx_p.h @@ -33,6 +33,7 @@ struct yaca_ctx_s { enum yaca_ctx_type_e type; + void (*ctx_destroy)(const yaca_ctx_h ctx); int (*get_output_length)(const yaca_ctx_h ctx, size_t input_len); }; diff --git a/src/digest.c b/src/digest.c index 3644fe0..d37d03f 100644 --- a/src/digest.c +++ b/src/digest.c @@ -38,7 +38,7 @@ struct yaca_digest_ctx_s EVP_MD_CTX *mdctx; }; -static struct yaca_digest_ctx_s *get_ctx(yaca_ctx_h ctx) +static struct yaca_digest_ctx_s *get_digest_ctx(const yaca_ctx_h ctx) { if (ctx == YACA_CTX_NULL) return NULL; @@ -54,7 +54,7 @@ static struct yaca_digest_ctx_s *get_ctx(yaca_ctx_h ctx) static int get_digest_output_length(const yaca_ctx_h ctx, size_t input_len) { - struct yaca_digest_ctx_s *c = get_ctx(ctx); + struct yaca_digest_ctx_s *c = get_digest_ctx(ctx); if (c == NULL) return YACA_ERROR_INVALID_ARGUMENT; @@ -62,10 +62,20 @@ static int get_digest_output_length(const yaca_ctx_h ctx, size_t input_len) return EVP_MD_size(c->md); } +static void destroy_digest_context(yaca_ctx_h ctx) +{ + struct yaca_digest_ctx_s *c = get_digest_ctx(ctx); + + if (c == NULL) + return; + + EVP_MD_CTX_destroy(c->mdctx); +} + API int yaca_digest_init(yaca_ctx_h *ctx, yaca_digest_algo_e algo) { - struct yaca_digest_ctx_s *nc; - int ret = YACA_ERROR_OPENSSL_FAILURE; + int ret; + struct yaca_digest_ctx_s *nc = NULL; if (ctx == NULL) return YACA_ERROR_INVALID_ARGUMENT; @@ -75,6 +85,7 @@ API int yaca_digest_init(yaca_ctx_h *ctx, yaca_digest_algo_e algo) return YACA_ERROR_OUT_OF_MEMORY; nc->ctx.type = YACA_CTX_DIGEST; + nc->ctx.ctx_destroy = destroy_digest_context; nc->ctx.get_output_length = get_digest_output_length; switch (algo) @@ -99,47 +110,58 @@ API int yaca_digest_init(yaca_ctx_h *ctx, yaca_digest_algo_e algo) break; default: ret = YACA_ERROR_INVALID_ARGUMENT; - goto err; + goto free; } - if (nc->md == NULL) - goto err; + if (nc->md == NULL) { + ret = YACA_ERROR_OPENSSL_FAILURE; + goto free; + } nc->mdctx = EVP_MD_CTX_create(); - if (nc->mdctx == NULL) - goto err; + if (nc->mdctx == NULL) { + ret = YACA_ERROR_OPENSSL_FAILURE; + goto free; + } ret = EVP_DigestInit(nc->mdctx, nc->md); - if (ret == 1) { - *ctx = (yaca_ctx_h)nc; - return 0; + if (ret != 1) { + ret = YACA_ERROR_OPENSSL_FAILURE; + goto ctx; } - ret = YACA_ERROR_OPENSSL_FAILURE; // TODO: yaca_get_error_code_from_openssl(ret); - EVP_MD_CTX_destroy(nc->mdctx); -err: - yaca_free(nc); + *ctx = (yaca_ctx_h)nc; + + ret = 0; + +ctx: + if (ret != 0) + EVP_MD_CTX_destroy(nc->mdctx); +free: + if (ret != 0) + yaca_free(nc); + return ret; } API int yaca_digest_update(yaca_ctx_h ctx, const char *data, size_t data_len) { - struct yaca_digest_ctx_s *c = get_ctx(ctx); + struct yaca_digest_ctx_s *c = get_digest_ctx(ctx); int ret; if (c == NULL || data == NULL || data_len == 0) return YACA_ERROR_INVALID_ARGUMENT; ret = EVP_DigestUpdate(c->mdctx, data, data_len); - if (ret == 1) - return 0; + if (ret != 1) + return YACA_ERROR_OPENSSL_FAILURE; - return YACA_ERROR_OPENSSL_FAILURE; // TODO: yaca_get_error_code_from_openssl(ret); + return 0; } API int yaca_digest_final(yaca_ctx_h ctx, char *digest, size_t *digest_len) { - struct yaca_digest_ctx_s *c = get_ctx(ctx); + struct yaca_digest_ctx_s *c = get_digest_ctx(ctx); int ret; unsigned len = 0; @@ -150,9 +172,10 @@ API int yaca_digest_final(yaca_ctx_h ctx, char *digest, size_t *digest_len) return YACA_ERROR_INVALID_ARGUMENT; ret = EVP_DigestFinal_ex(c->mdctx, (unsigned char*)digest, &len); + if (ret != 1) + return YACA_ERROR_OPENSSL_FAILURE; + *digest_len = len; - if (ret == 1) - return 0; - return YACA_ERROR_OPENSSL_FAILURE; // TODO: yaca_get_error_code_from_openssl(ret); + return 0; } -- 2.7.4 From cd542a7d422f6f837fe731fcf5d2b25edc201ef2 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Wed, 6 Apr 2016 14:33:39 +0200 Subject: [PATCH 02/16] Fix a SIGSEGV in key-exchange example. It's still not implemented though. Change-Id: I2ea56f1109d799d77c1a322567250afca68da13b --- examples/key_exchange.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/examples/key_exchange.c b/examples/key_exchange.c index 919cfaa..2377c20 100644 --- a/examples/key_exchange.c +++ b/examples/key_exchange.c @@ -36,19 +36,19 @@ void key_exchange_dh(void) yaca_key_h peer_key = YACA_KEY_NULL; yaca_key_h secret = YACA_KEY_NULL; + FILE *fp = NULL; + char *buffer = NULL; + long size; + // generate private, public key // add KEY_TYPE_PAIR_DH or use KEY_TYPE_PAIR_ECC and proper len? // imo add KEY_TYPE_PAIR_DH - ret = yaca_key_gen_pair(&private_key, &public_key, YACA_KEY_2048BIT, YACA_KEY_TYPE_PAIR_DH); + ret = yaca_key_gen_pair(&private_key, &public_key, YACA_KEY_TYPE_PAIR_DH, YACA_KEY_2048BIT); if (ret < 0) goto clean; // get peer public key from file // add helper to read key from file to buffer? - FILE *fp; - long size; - char *buffer; - fp = fopen("key.pub", "r"); if (!fp) goto clean; @@ -81,7 +81,8 @@ clean: yaca_key_free(public_key); yaca_key_free(peer_key); yaca_key_free(secret); - fclose(fp); + if (fp != NULL) + fclose(fp); yaca_free(buffer); } @@ -94,16 +95,16 @@ void key_exchange_ecdh(void) yaca_key_h peer_key = YACA_KEY_NULL; yaca_key_h secret = YACA_KEY_NULL; + FILE *fp = NULL; + char *buffer = NULL; + long size; + // generate private, public key - ret = yaca_key_gen_pair(&private_key, &public_key, YACA_KEY_CURVE_P256, YACA_KEY_TYPE_PAIR_ECC); + ret = yaca_key_gen_pair(&private_key, &public_key, YACA_KEY_TYPE_PAIR_ECC, YACA_KEY_CURVE_P256); if (ret < 0) goto clean; // get peer public key from file - FILE *fp; - long size; - char *buffer; - fp = fopen("key.pub", "r"); if (fp == NULL) goto clean; @@ -135,7 +136,8 @@ clean: yaca_key_free(public_key); yaca_key_free(peer_key); yaca_key_free(secret); - fclose(fp); + if (fp != NULL) + fclose(fp); yaca_free(buffer); } -- 2.7.4 From b89b251f93bf886e7b9fec11f3dd5f78871fdc36 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Wed, 6 Apr 2016 14:34:03 +0200 Subject: [PATCH 03/16] With cmake we should not allow the main git directory to be polluted. Change-Id: I24e334e7296af32c6e5de81cefb1ff8ece7305d2 --- .gitignore | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 6e51bb5..7115d13 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,3 @@ -*.o -*.d +build doc/html doc/man -*.a -*.so -- 2.7.4 From 0fee9cc18530a69139c5730466716bc6f3014ade Mon Sep 17 00:00:00 2001 From: Mateusz Kulikowski Date: Wed, 6 Apr 2016 13:27:33 +0200 Subject: [PATCH 04/16] Add coding rules document Based on internal discussions and tizen rules. Change-Id: Ibf4a65635bfd6adbc3259a28b948591e30d3f9c6 Signed-off-by: Mateusz Kulikowski --- doc/coding-rules.txt | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 doc/coding-rules.txt diff --git a/doc/coding-rules.txt b/doc/coding-rules.txt new file mode 100644 index 0000000..36660e4 --- /dev/null +++ b/doc/coding-rules.txt @@ -0,0 +1,106 @@ +-------------------------------------------------------------------------------- +1. Tizen rules that should be (partially) followed +-------------------------------------------------------------------------------- +Differences from Tizen rules are included as "Notes". For full description of +each rule - please refer to Tizen documentation. + +[R01] [CMT_M_C89] Style for comment is the C89 "/* … */" style. +Note: Temporary comments may use C99 style (TODO, FIXME etc.) + +[R02] [DEC_R_INL] inline keyword should sit between storage class and type. + +[R03] [IDT_R_TAB] Use tabs. All tabs are 4 characters. Indentation use only tab (No space key). +Note: If possible use Smart Tabs, if not - 4-character tabs + alignment spaces + +[R04] [IDT_R_SCH] Switch and case should be at the same indent. + +[R05] [IDT_R_LBL] goto labels aren't indented, allow a single space however. +Note: No single space allowed + +[M01] [SPC_M_KWD] Keywords have following space rules +-Put a space after (most) keywords (ex: if, switch, case, for, do, while). +-Exception: Do not put a space after function like keywords, such as sizeof, typeof, alignof, __attribute__. - + +[M02] [SPC_M_OPR] Operators have following space rules +-Put a space around(on each side of) most binary and ternary operators +-Example: = + -< > * / % | & ^ <= >= == != ? : +-Do not put a space after unary operators +-Example: & * + -~ ! +-Unary ++ and unary --are allowed no space on one side. +-Do not put a space after cast operator +-Do not put a space around the "." and "->" structure member operators. + +[M03] [SPC_M_SEP] Seperators have following space rules +-Put a space after closing brace when it has anything on the line. +-Exception : comma after closing brace '},' +-Put a space after comma +-Do not put space inside parenthesis '(', ')' +-Do not put a space after the function name in function calls. +-Do not put space before open square bracket '['; and inside square bracket '[', ']'. + +[M04] [BRC_M_FTN] functions have the opening brace at the beginning of the next line. + +[M05] [BRC_M_SMT] Statement brace: Open brace last on the line. The closing brace is empty on a line of its own. +-Exception: Where the closing race is followed by a continuation of the same statement, else should follow close brace '}', +while should follow close brace '}' + +[R06] [BRC_R_SST] Do not unnecessarily use braces where a single statement will do. +-Exception: if one branch of a conditional statement is a single statement, use braces in both branches. + +[R07] [LNE_R_TWS] No trailing whitespaces at the ends of lines. + +[R08] [LNE_R_EOF] Check for adding lines without a newline at end of file. +Notes: File should end with '\n' (single newline at the end of file) + +[R09] In source file, the sequence of the code organization : Copyright File comments Header files Define constant and macros Declare static (private) functions Define exported (public) functions Define static (private) functions Define protected functions. +Notes: Static (private) function code first, then functions used by other objects in library; API (public) functions at the end + +******** Public API should use 'API' macro - other functions are not visible outside of library + +[M07] Separate external public header(API) and internal header(declare protected functions that are not exported but use for many files) + +[M08] External public headers include the Doxygen style for comment. ex) Variable, Function, Struct. + +[M09] In function prototypes, include parameter names with their data types and return type. + +[R10] Macros with multiple statements should be enclosed in a "do -while" block. + +[R11] ''#' symbol for macro shall be located at the first column. + +[R12] In macro definition, every expression and the arguments in the expressions shall be enclosed by '(' and ')' for each. + +[R13] Don’t declare both a structure tag and variables or typedefs in the same declaration. +Note: Avoid use of typedefs for structures/enums unless it's needed (for handles in API etc.) + +[R14] Each variable shall be declared in the new line. +Notes: except for counters (like i, j, k, etc.). + +[M10] No mixed-case, Use underscores('_') to separate words in a name. + +[R15] Names of macros defining constants and labels in enums are composed of capital letters, numbers and '_' character. + +[R16] Name of functions are Verb + Noun to have a good representation of features. +Note: this is rule of thumb except for Public API. Public API has prefix (__fcn). + +-------------------------------------------------------------------------------- +2. Extra rules that should be followed +-------------------------------------------------------------------------------- + +- Line length + - soft limit (can be broken if expression will be more readable) 80 chars, + - hard limit 100 characters (should not be broken) +- Enums, structs, unions etc. should use brackets in newline (like functions) +- Typedefs should be used only where necessary (for example to make private implementations) +- Function arguments should either fit one line, or each parameter should be placed in separate line + +-------------------------------------------------------------------------------- +3. Tizen rules that should NOT be followed +-------------------------------------------------------------------------------- +[M06] [BRC_M_EUS] Open braces for enum, union and struct go on the same line. +Note: They go in new line - the same way as for functions + +[R17] Local functions whose scope is limited to the current source file have "static" keyword and names started with "__". +Note: static functions should not include "prefix" but can have arbitrary names (see R16). + +[R18] Names of protected(global) functions in internal header are started with '_' character. +Note: Functions shared between multiple objects can have arbitrary naming (see R16) -- 2.7.4 From cfb74118bf33130302358d03e5a9ce501b76a7db Mon Sep 17 00:00:00 2001 From: Mateusz Kulikowski Date: Mon, 4 Apr 2016 15:20:29 +0200 Subject: [PATCH 05/16] compilation: use c11 instead of c99 Change-Id: I1cea470f7ee346bf9cd38899c592fbc973568e83 Signed-off-by: Mateusz Kulikowski --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0da2f2c..bffb0dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,8 +52,8 @@ MESSAGE(STATUS "Compiler version: " ${CMAKE_C_COMPILER_VERSION}) MESSAGE(STATUS "Build type: " ${CMAKE_BUILD_TYPE}) MESSAGE(STATUS "-------------------------------------------------") -SET(CMAKE_C_FLAGS_DEBUG "-std=c99 -O0 -ggdb -Wp,-U_FORTIFY_SOURCE") -SET(CMAKE_C_FLAGS_RELEASE "-std=c99 -O2 -DNDEBUG") +SET(CMAKE_C_FLAGS_DEBUG "-std=c11 -O0 -ggdb -Wp,-U_FORTIFY_SOURCE") +SET(CMAKE_C_FLAGS_RELEASE "-std=c11 -O2 -DNDEBUG") ADD_DEFINITIONS("-fPIC") # Position Independent Code ADD_DEFINITIONS("-Werror") # Make all warnings into errors -- 2.7.4 From e5f65ce5b0923da3394a908b01d391b84d090c78 Mon Sep 17 00:00:00 2001 From: Mateusz Kulikowski Date: Thu, 7 Apr 2016 16:37:21 +0200 Subject: [PATCH 06/16] Remove private headers (*_p.h) Merge all internal defines / macros / declarations into internal.h This file may be later split, but for now it's small enough. Change-Id: I5f00c856fd7daa0773fd6ccdb175312df1e06818 Signed-off-by: Mateusz Kulikowski --- src/config.h | 24 ------------------------ src/crypto.c | 4 +--- src/digest.c | 4 +--- src/encrypt.c | 4 ++-- src/{ctx_p.h => internal.h} | 23 ++++++++++++++++++++--- src/key.c | 4 +--- src/key_p.h | 36 ------------------------------------ src/sign.c | 4 ++-- src/simple.c | 4 ++-- 9 files changed, 29 insertions(+), 78 deletions(-) delete mode 100644 src/config.h rename src/{ctx_p.h => internal.h} (77%) delete mode 100644 src/key_p.h diff --git a/src/config.h b/src/config.h deleted file mode 100644 index bc99feb..0000000 --- a/src/config.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Krzysztof Jackiewicz - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -#ifndef CONFIG_H -#define CONFIG_H - -#define API __attribute__ ((visibility ("default"))) - -#endif // CONFIG_H diff --git a/src/crypto.c b/src/crypto.c index dd24974..74c3f12 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -16,8 +16,6 @@ * limitations under the License */ -#include "config.h" - #include #include @@ -27,7 +25,7 @@ #include #include -#include "ctx_p.h" +#include "internal.h" API int yaca_init(void) { diff --git a/src/digest.c b/src/digest.c index d37d03f..f0acd71 100644 --- a/src/digest.c +++ b/src/digest.c @@ -16,8 +16,6 @@ * limitations under the License */ -#include "config.h" - #include #include @@ -28,7 +26,7 @@ #include #include -#include "ctx_p.h" +#include "internal.h" struct yaca_digest_ctx_s { diff --git a/src/encrypt.c b/src/encrypt.c index 427707a..ca8fa1d 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -16,8 +16,6 @@ * limitations under the License */ -#include "config.h" - #include #include @@ -26,6 +24,8 @@ #include #include +#include "internal.h" + API int yaca_encrypt_init(yaca_ctx_h *ctx, yaca_enc_algo_e algo, yaca_block_cipher_mode_e bcm, diff --git a/src/ctx_p.h b/src/internal.h similarity index 77% rename from src/ctx_p.h rename to src/internal.h index c8da49e..ea7d0ab 100644 --- a/src/ctx_p.h +++ b/src/internal.h @@ -16,12 +16,20 @@ * limitations under the License */ -#ifndef CTX_P_H -#define CTX_P_H +/** + * @file encrypt.h + * @brief Internal API + */ + +#ifndef INTERNAL_H +#define INTERNAL_H #include + #include +#define API __attribute__ ((visibility ("default"))) + enum yaca_ctx_type_e { YACA_CTX_INVALID = 0, @@ -37,4 +45,13 @@ struct yaca_ctx_s int (*get_output_length)(const yaca_ctx_h ctx, size_t input_len); }; -#endif // CTX_P_H + +/* Base structure for crypto keys - to be inherited */ +struct yaca_key_s +{ + yaca_key_type_e type; + + int (*get_key_length)(const struct yaca_key_s *key); +}; + +#endif diff --git a/src/key.c b/src/key.c index 2c70db8..e230156 100644 --- a/src/key.c +++ b/src/key.c @@ -16,8 +16,6 @@ * limitations under the License */ -#include "config.h" - #include #include #include @@ -31,7 +29,7 @@ #include #include -#include "key_p.h" +#include "internal.h" /** * Internal type for: diff --git a/src/key_p.h b/src/key_p.h deleted file mode 100644 index a431116..0000000 --- a/src/key_p.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Krzysztof Jackiewicz - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -#ifndef KEY_P_H -#define KEY_P_H - -#include -#include - -/** - * @file key_p.h - * @brief Private header for key.c - */ - -/* Base structure for crypto keys - to be inherited */ -struct yaca_key_s -{ - yaca_key_type_e type; -}; - -#endif /* KEY_P_H */ diff --git a/src/sign.c b/src/sign.c index 955a23b..2f37c0f 100644 --- a/src/sign.c +++ b/src/sign.c @@ -16,8 +16,6 @@ * limitations under the License */ -#include "config.h" - #include #include @@ -26,6 +24,8 @@ #include #include +#include "internal.h" + API int yaca_sign_init(yaca_ctx_h *ctx, yaca_digest_algo_e algo, const yaca_key_h key) diff --git a/src/simple.c b/src/simple.c index 312804e..ce1d5f3 100644 --- a/src/simple.c +++ b/src/simple.c @@ -16,8 +16,6 @@ * limitations under the License */ -#include "config.h" - #include #include @@ -30,6 +28,8 @@ #include #include +#include "internal.h" + API int yaca_digest_calc(yaca_digest_algo_e algo, const char *data, size_t data_len, -- 2.7.4 From aab278594e2a867ead3a190e07fca55c4b5cd737 Mon Sep 17 00:00:00 2001 From: Mateusz Kulikowski Date: Mon, 4 Apr 2016 15:23:38 +0200 Subject: [PATCH 07/16] digest: Add get_digest_algorithm Add API to translate yaca_digest_algo_e to EVP_MD. It is needed by other modules (like pbkdf2, message sign/verify etc.). Change-Id: I0b73eb51e076e443ebc269f96772c438479c81f5 Signed-off-by: Mateusz Kulikowski --- src/digest.c | 57 +++++++++++++++++++++++++++++++++++++-------------------- src/internal.h | 3 +++ 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/digest.c b/src/digest.c index f0acd71..8893e57 100644 --- a/src/digest.c +++ b/src/digest.c @@ -70,51 +70,68 @@ static void destroy_digest_context(yaca_ctx_h ctx) EVP_MD_CTX_destroy(c->mdctx); } -API int yaca_digest_init(yaca_ctx_h *ctx, yaca_digest_algo_e algo) +int get_digest_algorithm(yaca_digest_algo_e algo, const EVP_MD **md) { - int ret; - struct yaca_digest_ctx_s *nc = NULL; + int ret = 0; - if (ctx == NULL) + if (!md) return YACA_ERROR_INVALID_ARGUMENT; - nc = yaca_malloc(sizeof(struct yaca_digest_ctx_s)); - if (nc == NULL) - return YACA_ERROR_OUT_OF_MEMORY; - - nc->ctx.type = YACA_CTX_DIGEST; - nc->ctx.ctx_destroy = destroy_digest_context; - nc->ctx.get_output_length = get_digest_output_length; + *md = NULL; switch (algo) { case YACA_DIGEST_MD5: - nc->md = EVP_md5(); + *md = EVP_md5(); break; case YACA_DIGEST_SHA1: - nc->md = EVP_sha1(); + *md = EVP_sha1(); break; case YACA_DIGEST_SHA224: - nc->md = EVP_sha224(); + *md = EVP_sha224(); break; case YACA_DIGEST_SHA256: - nc->md = EVP_sha256(); + *md = EVP_sha256(); break; case YACA_DIGEST_SHA384: - nc->md = EVP_sha384(); + *md = EVP_sha384(); break; case YACA_DIGEST_SHA512: - nc->md = EVP_sha512(); + *md = EVP_sha512(); + break; + case YACA_DIGEST_CMAC: + ret = YACA_ERROR_NOT_IMPLEMENTED; break; default: ret = YACA_ERROR_INVALID_ARGUMENT; - goto free; + break; } - if (nc->md == NULL) { + if (ret == 0 && *md == NULL) ret = YACA_ERROR_OPENSSL_FAILURE; + + return ret; +} + +API int yaca_digest_init(yaca_ctx_h *ctx, yaca_digest_algo_e algo) +{ + int ret; + struct yaca_digest_ctx_s *nc = NULL; + + if (ctx == NULL) + return YACA_ERROR_INVALID_ARGUMENT; + + nc = yaca_malloc(sizeof(struct yaca_digest_ctx_s)); + if (nc == NULL) + return YACA_ERROR_OUT_OF_MEMORY; + + nc->ctx.type = YACA_CTX_DIGEST; + nc->ctx.ctx_destroy = destroy_digest_context; + nc->ctx.get_output_length = get_digest_output_length; + + ret = get_digest_algorithm(algo, &nc->md); + if (ret < 0) goto free; - } nc->mdctx = EVP_MD_CTX_create(); if (nc->mdctx == NULL) { diff --git a/src/internal.h b/src/internal.h index ea7d0ab..75d42c2 100644 --- a/src/internal.h +++ b/src/internal.h @@ -25,6 +25,7 @@ #define INTERNAL_H #include +#include #include @@ -54,4 +55,6 @@ struct yaca_key_s int (*get_key_length)(const struct yaca_key_s *key); }; +int get_digest_algorithm(yaca_digest_algo_e algo, const EVP_MD **md); + #endif -- 2.7.4 From 9ce0b9aa4c0d951859fbca69264d157e459a06a9 Mon Sep 17 00:00:00 2001 From: Mateusz Kulikowski Date: Wed, 6 Apr 2016 15:31:22 +0200 Subject: [PATCH 08/16] key: implement pbkdf2 - Fixup key_len - it is now size_t - Add maximum password length Change-Id: Ic5bc6de538f305020c52219793e2dc440de47eb3 Signed-off-by: Mateusz Kulikowski --- api/yaca/key.h | 2 +- src/key.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/api/yaca/key.h b/api/yaca/key.h index 342d733..7198ff3 100644 --- a/api/yaca/key.h +++ b/api/yaca/key.h @@ -184,7 +184,7 @@ int yaca_key_derive_pbkdf2(const char *password, size_t salt_len, int iter, yaca_digest_algo_e algo, - yaca_key_len_e key_len, + size_t key_len, yaca_key_h *key); // TODO: specify diff --git a/src/key.c b/src/key.c index e230156..41070da 100644 --- a/src/key.c +++ b/src/key.c @@ -20,6 +20,9 @@ #include #include #include +#include + +#include #include #include @@ -390,8 +393,45 @@ API int yaca_key_derive_pbkdf2(const char *password, size_t salt_len, int iter, yaca_digest_algo_e algo, - yaca_key_len_e key_len, + size_t key_len, yaca_key_h *key) { - return YACA_ERROR_NOT_IMPLEMENTED; + const EVP_MD *md; + struct yaca_key_simple_s *nk; + int ret; + + if (password == NULL || salt == NULL || salt_len == 0 || + iter == 0 || key_len == 0 || key == NULL) + return YACA_ERROR_INVALID_ARGUMENT; + + ret = get_digest_algorithm(algo, &md); + if (ret < 0) + return ret; + + if (key_len % 8) /* Key length must be multiple of 8-bits */ + return YACA_ERROR_INVALID_ARGUMENT; + + if (key_len > SIZE_MAX - sizeof(struct yaca_key_simple_s)) + return YACA_ERROR_TOO_BIG_ARGUMENT; + + nk = yaca_malloc(sizeof(struct yaca_key_simple_s) + key_len); + if (nk == NULL) + return YACA_ERROR_OUT_OF_MEMORY; + + nk->length = key_len; + nk->key.type = YACA_KEY_TYPE_SYMMETRIC; // TODO: how to handle other keys? + + ret = PKCS5_PBKDF2_HMAC(password, -1, (const unsigned char*)salt, + salt_len, iter, md, key_len / 8, + (unsigned char*)nk->d); + if (ret != 1) { + ret = YACA_ERROR_OPENSSL_FAILURE; // TODO: yaca_get_error_code_from_openssl(ret); + goto err; + } + + *key = (yaca_key_h)nk; + return 0; +err: + yaca_free(nk); + return ret; } -- 2.7.4 From 668268c553ad5cdc9bf98e4ec9898a48d86af3cd Mon Sep 17 00:00:00 2001 From: Mateusz Kulikowski Date: Wed, 6 Apr 2016 15:32:10 +0200 Subject: [PATCH 09/16] key: Check for key_len overflows Affected functions: - key_import - key_gen Change-Id: I1b2898b03d3bf950706c21671afe9d6a89311255 Signed-off-by: Mateusz Kulikowski --- src/key.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/key.c b/src/key.c index 41070da..426ec6d 100644 --- a/src/key.c +++ b/src/key.c @@ -155,7 +155,7 @@ API int yaca_key_import(yaca_key_h *key, struct yaca_key_simple_s *nk = NULL; yaca_key_h k; - if (sizeof(struct yaca_key_s) + data_len < data_len) + if (data_len > SIZE_MAX - sizeof(struct yaca_key_simple_s)) return YACA_ERROR_TOO_BIG_ARGUMENT; nk = yaca_malloc(sizeof(struct yaca_key_simple_s) + data_len); @@ -230,6 +230,8 @@ API int yaca_key_gen(yaca_key_h *sym_key, if (key_type != YACA_KEY_TYPE_SYMMETRIC && key_type != YACA_KEY_TYPE_IV) return YACA_ERROR_NOT_IMPLEMENTED; + if (key_len > SIZE_MAX - sizeof(struct yaca_key_simple_s)) + return YACA_ERROR_TOO_BIG_ARGUMENT; nk = yaca_malloc(sizeof(struct yaca_key_simple_s) + key_len); if (nk == NULL) -- 2.7.4 From a75b4108770d47157886ede13774eeab3a858d08 Mon Sep 17 00:00:00 2001 From: Mateusz Kulikowski Date: Wed, 6 Apr 2016 15:33:39 +0200 Subject: [PATCH 10/16] key: Cleanups - Clean import for symmetric keys - Clean generation of "simple/single" keys - Return proper error from yaca_key_gen (key not supported vs invalid type) Change-Id: Ia993ad1b1908dd9c5babc31b687e2e9b9bc07eba Signed-off-by: Mateusz Kulikowski --- src/key.c | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/src/key.c b/src/key.c index 426ec6d..41000d2 100644 --- a/src/key.c +++ b/src/key.c @@ -153,7 +153,6 @@ API int yaca_key_import(yaca_key_h *key, if (key_type == YACA_KEY_TYPE_SYMMETRIC) { struct yaca_key_simple_s *nk = NULL; - yaca_key_h k; if (data_len > SIZE_MAX - sizeof(struct yaca_key_simple_s)) return YACA_ERROR_TOO_BIG_ARGUMENT; @@ -164,10 +163,9 @@ API int yaca_key_import(yaca_key_h *key, memcpy(nk->d, data, data_len); /* TODO: CRYPTO_/EVP_... */ nk->length = data_len * 8; + nk->key.type = key_type; - k = (yaca_key_h)nk; - k->type = key_type; - *key = k; + *key = (yaca_key_h)nk; return 0; } @@ -227,9 +225,29 @@ API int yaca_key_gen(yaca_key_h *sym_key, if (sym_key == NULL) return YACA_ERROR_INVALID_ARGUMENT; - if (key_type != YACA_KEY_TYPE_SYMMETRIC && - key_type != YACA_KEY_TYPE_IV) + switch(key_type) + { + case YACA_KEY_TYPE_SYMMETRIC: + case YACA_KEY_TYPE_IV: + break; + case YACA_KEY_TYPE_DES: + case YACA_KEY_TYPE_RSA_PUB: /**< RSA public key */ + case YACA_KEY_TYPE_RSA_PRIV: /**< RSA private key */ + case YACA_KEY_TYPE_DSA_PUB: /**< DSA public key */ + case YACA_KEY_TYPE_DSA_PRIV: /**< DSA private key */ + case YACA_KEY_TYPE_DH_PUB: /**< Diffie-Hellman public key */ + case YACA_KEY_TYPE_DH_PRIV: /**< Diffie-Hellman private key */ + case YACA_KEY_TYPE_ECC_PUB: /**< ECC public key */ + case YACA_KEY_TYPE_ECC_PRIV: /**< ECC private key */ + case YACA_KEY_TYPE_PAIR_RSA: /**< Pair of RSA keys */ + case YACA_KEY_TYPE_PAIR_DSA: /**< Pair of DSA keys */ + case YACA_KEY_TYPE_PAIR_DH: /**< Pair of Diffie-Hellman keys */ + case YACA_KEY_TYPE_PAIR_ECC: /**< Pair of ECC keys */ return YACA_ERROR_NOT_IMPLEMENTED; + default: + return YACA_ERROR_INVALID_ARGUMENT; + } + if (key_len > SIZE_MAX - sizeof(struct yaca_key_simple_s)) return YACA_ERROR_TOO_BIG_ARGUMENT; @@ -238,20 +256,18 @@ API int yaca_key_gen(yaca_key_h *sym_key, return YACA_ERROR_OUT_OF_MEMORY; nk->length = key_len; + nk->key.type = key_type; ret = yaca_rand_bytes(nk->d, key_len); if (ret != 0) - goto free; + goto err; *sym_key = (yaca_key_h)nk; - (*sym_key)->type = key_type; - - ret = 0; -free: - if (ret != 0) - yaca_free(nk); + return 0; +err: + yaca_free(nk); return ret; } -- 2.7.4 From 372c0a8ee63467eaaa0248342a9252672e10d0fe Mon Sep 17 00:00:00 2001 From: Mateusz Kulikowski Date: Fri, 8 Apr 2016 12:25:37 +0200 Subject: [PATCH 11/16] Convert all key lengths to bits - Rename API parameters to avoid confusion (key_len -> key_bits) - Rename internal key length to key_bits - Fix key length handling where it was done incorrectly Change-Id: If3dcf8ad87246a144019d3fc93c6251c3529d881 Signed-off-by: Mateusz Kulikowski --- api/yaca/crypto.h | 8 ++++---- api/yaca/key.h | 16 ++++++++-------- api/yaca/types.h | 2 +- src/crypto.c | 2 +- src/key.c | 42 ++++++++++++++++++++++-------------------- 5 files changed, 36 insertions(+), 34 deletions(-) diff --git a/api/yaca/crypto.h b/api/yaca/crypto.h index 526bda3..66d77e6 100644 --- a/api/yaca/crypto.h +++ b/api/yaca/crypto.h @@ -165,15 +165,15 @@ int yaca_get_output_length(const yaca_ctx_h ctx, size_t input_len); /** * @brief yaca_get_iv_length Returns the recomended/default length of the IV for a given encryption configuration. * - * @param[in] algo Encryption algorithm. - * @param[in] bcm Chain mode. - * @param[in] key_len Key length (@see crypto_key_len_e). + * @param[in] algo Encryption algorithm. + * @param[in] bcm Chain mode. + * @param[in] key_bits Key length in bits (@see crypto_key_len_e). * * @return negative on error (@see error.h) or the IV length. */ int yaca_get_iv_length(yaca_enc_algo_e algo, yaca_block_cipher_mode_e bcm, - size_t key_len); + size_t key_bits); /**@}*/ diff --git a/api/yaca/key.h b/api/yaca/key.h index 7198ff3..b479867 100644 --- a/api/yaca/key.h +++ b/api/yaca/key.h @@ -48,7 +48,7 @@ extern "C" { * * @param[in] key Key which length we return. * - * @return negative on error (@see error.h) or key length. + * @return negative on error (@see error.h) or key length (in bits). */ int yaca_key_get_length(const yaca_key_h key); @@ -91,13 +91,13 @@ int yaca_key_export(const yaca_key_h key, * * @param[out] sym_key Newly generated key (must be freed with @see yaca_key_free). * @param[in] key_type Type of the key to be generated. - * @param[in] key_len Length of the key to be generated. + * @param[in] key_bits Length of the key (in bits) to be generated. * * @return 0 on success, negative on error (@see error.h). */ int yaca_key_gen(yaca_key_h *sym_key, yaca_key_type_e key_type, - size_t key_len); + size_t key_bits); /** * @brief yaca_key_gen_pair Generates a new key pair. @@ -105,18 +105,18 @@ int yaca_key_gen(yaca_key_h *sym_key, * @param[out] prv_key Newly generated private key (must be freed with @see yaca_key_free). * @param[out] pub_key Newly generated public key (must be freed with @see yaca_key_free). * @param[in] key_type Type of the key to be generated (must be YACA_KEY_TYPE_PAIR*). - * @param[in] key_len Length of the key to be generated. + * @param[in] key_bits Length of the key (in bits) to be generated. * * @return 0 on success, negative on error (@see error.h). */ int yaca_key_gen_pair(yaca_key_h *prv_key, yaca_key_h *pub_key, yaca_key_type_e key_type, - size_t key_len); + size_t key_bits); /** * @brief yaca_key_free Frees the key created by the library. - * Passing YACA_KEY_NULL is allowed. + * Passing YACA_KEY_NULL is allowed. * * @param key Key to be freed. * @@ -174,7 +174,7 @@ int yaca_key_derive_kea(const yaca_key_h prv_key, * @param[in] salt_len Length of the salt. * @param[in] iter Number of iterations. (TODO: add enum to proposed number of iterations, pick sane defaults). * @param[in] algo Digest algorithm that should be used in key generation. (TODO: sane defaults). - * @param[in] key_len Length of a key to be generated. + * @param[in] key_bits Length of a key (in bits) to be generated. * @param[out] key Newly generated key (must be freed with @see yaca_key_free). * * @return 0 on success, negative on error (@see error.h). @@ -184,7 +184,7 @@ int yaca_key_derive_pbkdf2(const char *password, size_t salt_len, int iter, yaca_digest_algo_e algo, - size_t key_len, + size_t key_bits, yaca_key_h *key); // TODO: specify diff --git a/api/yaca/types.h b/api/yaca/types.h index 020af4d..c4e52b8 100644 --- a/api/yaca/types.h +++ b/api/yaca/types.h @@ -105,7 +105,7 @@ typedef enum { YACA_KEY_2048BIT = 2048, YACA_KEY_3072BIT = 3072, YACA_KEY_4096BIT = 4096 -} yaca_key_len_e; +} yaca_key_bits_e; /** * @brief Message digest algorithms. CMAC is included to simplify API diff --git a/src/crypto.c b/src/crypto.c index 74c3f12..b77e9a2 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -108,7 +108,7 @@ API int yaca_get_output_length(const yaca_ctx_h ctx, size_t input_len) API int yaca_get_iv_length(yaca_enc_algo_e algo, yaca_block_cipher_mode_e bcm, - size_t key_len) + size_t key_bits) { return YACA_ERROR_NOT_IMPLEMENTED; } diff --git a/src/key.c b/src/key.c index 41000d2..b169bc3 100644 --- a/src/key.c +++ b/src/key.c @@ -44,7 +44,7 @@ struct yaca_key_simple_s { struct yaca_key_s key; - size_t length; + size_t bits; char d[0]; }; @@ -99,8 +99,8 @@ static struct yaca_key_evp_s *get_evp_key(const yaca_key_h key) static inline void simple_key_sanity_check(const struct yaca_key_simple_s *key) { - assert(key->length); - assert(key->length % 8 == 0); + assert(key->bits); + assert(key->bits % 8 == 0); } // TODO: do we need a sanity check sanity for Evp keys? @@ -128,7 +128,7 @@ API int yaca_key_get_length(const yaca_key_h key) if (simple_key != NULL) { simple_key_sanity_check(simple_key); - return simple_key->length; + return simple_key->bits; } if (evp_key != NULL) { @@ -162,7 +162,7 @@ API int yaca_key_import(yaca_key_h *key, return YACA_ERROR_OUT_OF_MEMORY; memcpy(nk->d, data, data_len); /* TODO: CRYPTO_/EVP_... */ - nk->length = data_len * 8; + nk->bits = data_len * 8; nk->key.type = key_type; *key = (yaca_key_h)nk; @@ -198,7 +198,7 @@ API int yaca_key_export(const yaca_key_h key, if (simple_key != NULL) { simple_key_sanity_check(simple_key); - byte_len = simple_key->length / 8; + byte_len = simple_key->bits / 8; *data = yaca_malloc(byte_len); memcpy(*data, simple_key->d, byte_len); *data_len = byte_len; @@ -217,10 +217,11 @@ API int yaca_key_export(const yaca_key_h key, API int yaca_key_gen(yaca_key_h *sym_key, yaca_key_type_e key_type, - size_t key_len) + size_t key_bits) { int ret; struct yaca_key_simple_s *nk = NULL; + size_t key_byte_len = key_bits / 8; if (sym_key == NULL) return YACA_ERROR_INVALID_ARGUMENT; @@ -248,17 +249,17 @@ API int yaca_key_gen(yaca_key_h *sym_key, return YACA_ERROR_INVALID_ARGUMENT; } - if (key_len > SIZE_MAX - sizeof(struct yaca_key_simple_s)) + if (key_byte_len > SIZE_MAX - sizeof(struct yaca_key_simple_s)) return YACA_ERROR_TOO_BIG_ARGUMENT; - nk = yaca_malloc(sizeof(struct yaca_key_simple_s) + key_len); + nk = yaca_malloc(sizeof(struct yaca_key_simple_s) + key_byte_len); if (nk == NULL) return YACA_ERROR_OUT_OF_MEMORY; - nk->length = key_len; + nk->bits = key_bits; nk->key.type = key_type; - ret = yaca_rand_bytes(nk->d, key_len); + ret = yaca_rand_bytes(nk->d, key_byte_len); if (ret != 0) goto err; @@ -274,7 +275,7 @@ err: API int yaca_key_gen_pair(yaca_key_h *prv_key, yaca_key_h *pub_key, yaca_key_type_e key_type, - size_t key_len) + size_t key_bits) { int ret; struct yaca_key_evp_s *nk_prv = NULL; @@ -319,7 +320,7 @@ API int yaca_key_gen_pair(yaca_key_h *prv_key, goto free_bne; } - ret = RSA_generate_key_ex(rsa, key_len, bne, NULL); + ret = RSA_generate_key_ex(rsa, key_bits, bne, NULL); if (ret != 1) { ret = YACA_ERROR_OPENSSL_FAILURE; goto free_rsa; @@ -411,36 +412,37 @@ API int yaca_key_derive_pbkdf2(const char *password, size_t salt_len, int iter, yaca_digest_algo_e algo, - size_t key_len, + size_t key_bits, yaca_key_h *key) { const EVP_MD *md; struct yaca_key_simple_s *nk; + size_t key_byte_len = key_bits / 8; int ret; if (password == NULL || salt == NULL || salt_len == 0 || - iter == 0 || key_len == 0 || key == NULL) + iter == 0 || key_bits == 0 || key == NULL) return YACA_ERROR_INVALID_ARGUMENT; ret = get_digest_algorithm(algo, &md); if (ret < 0) return ret; - if (key_len % 8) /* Key length must be multiple of 8-bits */ + if (key_bits % 8) /* Key length must be multiple of 8-bits */ return YACA_ERROR_INVALID_ARGUMENT; - if (key_len > SIZE_MAX - sizeof(struct yaca_key_simple_s)) + if (key_byte_len > SIZE_MAX - sizeof(struct yaca_key_simple_s)) return YACA_ERROR_TOO_BIG_ARGUMENT; - nk = yaca_malloc(sizeof(struct yaca_key_simple_s) + key_len); + nk = yaca_malloc(sizeof(struct yaca_key_simple_s) + key_byte_len); if (nk == NULL) return YACA_ERROR_OUT_OF_MEMORY; - nk->length = key_len; + nk->bits = key_bits; nk->key.type = YACA_KEY_TYPE_SYMMETRIC; // TODO: how to handle other keys? ret = PKCS5_PBKDF2_HMAC(password, -1, (const unsigned char*)salt, - salt_len, iter, md, key_len / 8, + salt_len, iter, md, key_byte_len, (unsigned char*)nk->d); if (ret != 1) { ret = YACA_ERROR_OPENSSL_FAILURE; // TODO: yaca_get_error_code_from_openssl(ret); -- 2.7.4 From c971d9b0bd5327c72e8f449832a7084e4b810445 Mon Sep 17 00:00:00 2001 From: Mateusz Kulikowski Date: Fri, 8 Apr 2016 12:48:07 +0200 Subject: [PATCH 12/16] Move key structures to internal API header, expose getters - Rename get_evp|simple_key to key_get_evp|simple and expose as internal API - Move key structures to internal API header Change-Id: I192d456b90043446e93b788fab5c9e5625dfd3f6 Signed-off-by: Mateusz Kulikowski --- src/internal.h | 33 ++++++++++++++++++++++ src/key.c | 86 +++++++++++++++++++--------------------------------------- 2 files changed, 61 insertions(+), 58 deletions(-) diff --git a/src/internal.h b/src/internal.h index 75d42c2..a1bc9a6 100644 --- a/src/internal.h +++ b/src/internal.h @@ -55,6 +55,39 @@ struct yaca_key_s int (*get_key_length)(const struct yaca_key_s *key); }; +/** + * Internal type for: + * - YACA_KEY_TYPE_SYMMETRIC + * - YACA_KEY_TYPE_DES + * - YACA_KEY_TYPE_IV + */ +struct yaca_key_simple_s +{ + struct yaca_key_s key; + + size_t bits; + char d[0]; +}; + +/** + * Internal type for: + * - YACA_KEY_TYPE_RSA_PUB + * - YACA_KEY_TYPE_RSA_PRIV + * - YACA_KEY_TYPE_DSA_PUB + * - YACA_KEY_TYPE_DSA_PRIV + * + * TODO: and possibly others (for every key that uses EVP_PKEY) + */ +struct yaca_key_evp_s +{ + struct yaca_key_s key; + + EVP_PKEY *evp; +}; + int get_digest_algorithm(yaca_digest_algo_e algo, const EVP_MD **md); +struct yaca_key_simple_s *key_get_simple(const yaca_key_h key); +struct yaca_key_evp_s *key_get_evp(const yaca_key_h key); + #endif diff --git a/src/key.c b/src/key.c index b169bc3..9de4611 100644 --- a/src/key.c +++ b/src/key.c @@ -34,37 +34,31 @@ #include "internal.h" -/** - * Internal type for: - * - YACA_KEY_TYPE_SYMMETRIC - * - YACA_KEY_TYPE_DES - * - YACA_KEY_TYPE_IV - */ -struct yaca_key_simple_s +static inline void simple_key_sanity_check(const struct yaca_key_simple_s *key) { - struct yaca_key_s key; - - size_t bits; - char d[0]; -}; - -/** - * Internal type for: - * - YACA_KEY_TYPE_RSA_PUB - * - YACA_KEY_TYPE_RSA_PRIV - * - YACA_KEY_TYPE_DSA_PUB - * - YACA_KEY_TYPE_DSA_PRIV - * - * TODO: and possibly others (for every key that uses EVP_PKEY) - */ -struct yaca_key_evp_s + assert(key->bits); + assert(key->bits % 8 == 0); +} + +// TODO: do we need a sanity check sanity for Evp keys? +static inline void evp_key_sanity_check(const struct yaca_key_evp_s *key) +{ +} + +// TODO: do we need this variant? or the two above are enough? +static inline void key_sanity_check(const yaca_key_h key) { - struct yaca_key_s key; + const struct yaca_key_simple_s *simple_key = key_get_simple(key); + const struct yaca_key_evp_s *evp_key = key_get_evp(key); - EVP_PKEY *evp; -}; + if (simple_key != NULL) + simple_key_sanity_check(simple_key); -static struct yaca_key_simple_s *get_simple_key(const yaca_key_h key) + if (evp_key != NULL) + evp_key_sanity_check(evp_key); +} + +struct yaca_key_simple_s *key_get_simple(const yaca_key_h key) { if (key == YACA_KEY_NULL) return NULL; @@ -80,7 +74,7 @@ static struct yaca_key_simple_s *get_simple_key(const yaca_key_h key) } } -static struct yaca_key_evp_s *get_evp_key(const yaca_key_h key) +struct yaca_key_evp_s *key_get_evp(const yaca_key_h key) { if (key == YACA_KEY_NULL) return NULL; @@ -97,34 +91,10 @@ static struct yaca_key_evp_s *get_evp_key(const yaca_key_h key) } } -static inline void simple_key_sanity_check(const struct yaca_key_simple_s *key) -{ - assert(key->bits); - assert(key->bits % 8 == 0); -} - -// TODO: do we need a sanity check sanity for Evp keys? -static inline void evp_key_sanity_check(const struct yaca_key_evp_s *key) -{ -} - -// TODO: do we need this variant? or the two above are enough? -static inline void key_sanity_check(const yaca_key_h key) -{ - const struct yaca_key_simple_s *simple_key = get_simple_key(key); - const struct yaca_key_evp_s *evp_key = get_evp_key(key); - - if (simple_key != NULL) - simple_key_sanity_check(simple_key); - - if (evp_key != NULL) - evp_key_sanity_check(evp_key); -} - API int yaca_key_get_length(const yaca_key_h key) { - const struct yaca_key_simple_s *simple_key = get_simple_key(key); - const struct yaca_key_evp_s *evp_key = get_evp_key(key); + const struct yaca_key_simple_s *simple_key = key_get_simple(key); + const struct yaca_key_evp_s *evp_key = key_get_evp(key); if (simple_key != NULL) { simple_key_sanity_check(simple_key); @@ -186,8 +156,8 @@ API int yaca_key_export(const yaca_key_h key, size_t *data_len) { size_t byte_len; - struct yaca_key_simple_s *simple_key = get_simple_key(key); - struct yaca_key_evp_s *evp_key = get_evp_key(key); + struct yaca_key_simple_s *simple_key = key_get_simple(key); + struct yaca_key_evp_s *evp_key = key_get_evp(key); if (data == NULL || data_len == NULL) return YACA_ERROR_INVALID_ARGUMENT; @@ -379,8 +349,8 @@ free_prv: API void yaca_key_free(yaca_key_h key) { - struct yaca_key_simple_s *simple_key = get_simple_key(key); - struct yaca_key_evp_s *evp_key = get_evp_key(key); + struct yaca_key_simple_s *simple_key = key_get_simple(key); + struct yaca_key_evp_s *evp_key = key_get_evp(key); if (simple_key != NULL) yaca_free(simple_key); -- 2.7.4 From 6f48732023cc006e21c1680a19e3db263760d189 Mon Sep 17 00:00:00 2001 From: Mateusz Kulikowski Date: Fri, 8 Apr 2016 12:49:31 +0200 Subject: [PATCH 13/16] Rename get_digest_algorithm -> digest_get_algorithm Use common naming for internal API Change-Id: Ie6dce91fca60d099249e32938b9ebc5dd8a1a6d2 Signed-off-by: Mateusz Kulikowski --- src/digest.c | 4 ++-- src/internal.h | 2 +- src/key.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/digest.c b/src/digest.c index 8893e57..4cc0ceb 100644 --- a/src/digest.c +++ b/src/digest.c @@ -70,7 +70,7 @@ static void destroy_digest_context(yaca_ctx_h ctx) EVP_MD_CTX_destroy(c->mdctx); } -int get_digest_algorithm(yaca_digest_algo_e algo, const EVP_MD **md) +int digest_get_algorithm(yaca_digest_algo_e algo, const EVP_MD **md) { int ret = 0; @@ -129,7 +129,7 @@ API int yaca_digest_init(yaca_ctx_h *ctx, yaca_digest_algo_e algo) nc->ctx.ctx_destroy = destroy_digest_context; nc->ctx.get_output_length = get_digest_output_length; - ret = get_digest_algorithm(algo, &nc->md); + ret = digest_get_algorithm(algo, &nc->md); if (ret < 0) goto free; diff --git a/src/internal.h b/src/internal.h index a1bc9a6..6aefaa8 100644 --- a/src/internal.h +++ b/src/internal.h @@ -85,7 +85,7 @@ struct yaca_key_evp_s EVP_PKEY *evp; }; -int get_digest_algorithm(yaca_digest_algo_e algo, const EVP_MD **md); +int digest_get_algorithm(yaca_digest_algo_e algo, const EVP_MD **md); struct yaca_key_simple_s *key_get_simple(const yaca_key_h key); struct yaca_key_evp_s *key_get_evp(const yaca_key_h key); diff --git a/src/key.c b/src/key.c index 9de4611..65245d0 100644 --- a/src/key.c +++ b/src/key.c @@ -394,7 +394,7 @@ API int yaca_key_derive_pbkdf2(const char *password, iter == 0 || key_bits == 0 || key == NULL) return YACA_ERROR_INVALID_ARGUMENT; - ret = get_digest_algorithm(algo, &md); + ret = digest_get_algorithm(algo, &md); if (ret < 0) return ret; -- 2.7.4 From 72833a0f34413ad54a44042e3f3f08a7e363c6f1 Mon Sep 17 00:00:00 2001 From: Mateusz Kulikowski Date: Mon, 11 Apr 2016 11:43:04 +0200 Subject: [PATCH 14/16] yaca_ctx_free: NULL context handling Ignore null contexts. Change-Id: I7ecac9603519d91d5708f4eed11af0a9f8a4ce17 Signed-off-by: Mateusz Kulikowski --- src/crypto.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/crypto.c b/src/crypto.c index b77e9a2..af73404 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -94,8 +94,10 @@ API int yaca_ctx_get_param(const yaca_ctx_h ctx, yaca_ex_param_e param, API void yaca_ctx_free(yaca_ctx_h ctx) { - ctx->ctx_destroy(ctx); - yaca_free(ctx); + if (ctx != YACA_CTX_NULL) { + ctx->ctx_destroy(ctx); + yaca_free(ctx); + } } API int yaca_get_output_length(const yaca_ctx_h ctx, size_t input_len) -- 2.7.4 From a8733e8a18c0b9261987108ee2c937f624e53546 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Fri, 8 Apr 2016 16:26:48 +0200 Subject: [PATCH 15/16] Fix compilation with Clang. Some bugs in the code fixed, caught by Clang warnings/errors. Change-Id: If6b2b617222ea8d07d5d3af4202a4dae3b7ebebe Signed-off-by: Lukasz Pawelczyk --- examples/encrypt.c | 5 +++-- examples/encrypt_aes_gcm.c | 8 ++++---- examples/lorem.c | 2 +- examples/sign.c | 6 +++--- src/key.c | 2 ++ 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/examples/encrypt.c b/examples/encrypt.c index 26f21e8..8ca1bc1 100644 --- a/examples/encrypt.c +++ b/examples/encrypt.c @@ -100,7 +100,7 @@ void encrypt_advanced(void) if (ret) return; - ret = yaca_key_gen(&iv, YACA_KEY_IV_256BIT, YACA_KEY_TYPE_SYMMETRIC); + ret = yaca_key_gen(&iv, YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_IV_256BIT); if (ret) goto ex_key; @@ -208,7 +208,8 @@ void encrypt_seal(void) /// Generate key pair ret = yaca_key_gen_pair(&key_priv, &key_pub, - YACA_KEY_2048BIT, YACA_KEY_TYPE_PAIR_RSA); + YACA_KEY_TYPE_PAIR_RSA, + YACA_KEY_2048BIT); if (ret) return; /// Encrypt a.k.a. seal diff --git a/examples/encrypt_aes_gcm.c b/examples/encrypt_aes_gcm.c index bd65c0d..3976170 100644 --- a/examples/encrypt_aes_gcm.c +++ b/examples/encrypt_aes_gcm.c @@ -36,7 +36,7 @@ void encrypt_decrypt_aes_gcm(void) { int ret; - yaca_ctx_h ctx; + yaca_ctx_h ctx = YACA_CTX_NULL; yaca_key_h key = YACA_KEY_NULL; yaca_key_h iv = YACA_KEY_NULL; @@ -55,17 +55,17 @@ void encrypt_decrypt_aes_gcm(void) /// Key generation - ret = yaca_key_gen(&key, YACA_KEY_256BIT, YACA_KEY_TYPE_SYMMETRIC); // key_type, key_len, *key ? looks imo much better + ret = yaca_key_gen(&key, YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_256BIT); // key_type, key_len, *key ? looks imo much better if (ret < 0) goto clean; // use YACA_KEY_IV_128BIT & YACA_KEY_TYPE_IV or maybe YACA_KEY_128BIT & YACA_KEY_TYPE_SYMMETRIC ? - ret = yaca_key_gen(&iv, YACA_KEY_IV_128BIT, YACA_KEY_TYPE_IV); + ret = yaca_key_gen(&iv, YACA_KEY_TYPE_IV, YACA_KEY_IV_128BIT); if (ret < 0) goto clean; // use YACA_KEY_128BIT & YACA_KEY_TYPE_SYMMETRIC or maybe add YACA_KEY_AAD_128BIT & YACA_KEY_TYPE_AAD ? - ret = yaca_key_gen(&aad_key, YACA_KEY_UNSAFE_128BIT, YACA_KEY_TYPE_SYMMETRIC); + ret = yaca_key_gen(&aad_key, YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_UNSAFE_128BIT); if (ret < 0) goto clean; diff --git a/examples/lorem.c b/examples/lorem.c index cfeaebb..ac6955f 100644 --- a/examples/lorem.c +++ b/examples/lorem.c @@ -18,7 +18,7 @@ /** * @file lorem.c - * @brief + * @brief Lorem Ipsum */ const char *lorem8 = "Lorem i"; diff --git a/examples/sign.c b/examples/sign.c index eb3fc28..dbec172 100644 --- a/examples/sign.c +++ b/examples/sign.c @@ -110,7 +110,7 @@ void sign_verify_rsa(void) // GENERATE - if (yaca_key_gen_pair(&prv, &pub, YACA_KEY_4096BIT, YACA_KEY_TYPE_PAIR_RSA)) + if (yaca_key_gen_pair(&prv, &pub, YACA_KEY_TYPE_PAIR_RSA, YACA_KEY_4096BIT)) return; @@ -160,7 +160,7 @@ void sign_verify_hmac(void) // GENERATE - if (yaca_key_gen(&key, YACA_KEY_256BIT, YACA_KEY_TYPE_SYMMETRIC)) + if (yaca_key_gen(&key, YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_256BIT)) return; // SIGN @@ -197,7 +197,7 @@ void sign_verify_cmac(void) // GENERATE - if( yaca_key_gen(&key, YACA_KEY_256BIT, YACA_KEY_TYPE_SYMMETRIC)) + if( yaca_key_gen(&key, YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_256BIT)) return; // SIGN diff --git a/src/key.c b/src/key.c index 65245d0..78dd5c8 100644 --- a/src/key.c +++ b/src/key.c @@ -46,6 +46,7 @@ static inline void evp_key_sanity_check(const struct yaca_key_evp_s *key) } // TODO: do we need this variant? or the two above are enough? +#if 0 static inline void key_sanity_check(const yaca_key_h key) { const struct yaca_key_simple_s *simple_key = key_get_simple(key); @@ -57,6 +58,7 @@ static inline void key_sanity_check(const yaca_key_h key) if (evp_key != NULL) evp_key_sanity_check(evp_key); } +#endif struct yaca_key_simple_s *key_get_simple(const yaca_key_h key) { -- 2.7.4 From a4216c9caa65f8d2466ef00e0eb0136ce28e3193 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Mon, 11 Apr 2016 14:24:27 +0200 Subject: [PATCH 16/16] Enable extra compilation flags. Change-Id: I689300d8176eacdad75ddf19bb1b3f91510e872d --- CMakeLists.txt | 12 +++++++----- src/internal.h | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bffb0dd..a42b702 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,16 +58,18 @@ SET(CMAKE_C_FLAGS_RELEASE "-std=c11 -O2 -DNDEBUG") ADD_DEFINITIONS("-fPIC") # Position Independent Code ADD_DEFINITIONS("-Werror") # Make all warnings into errors ADD_DEFINITIONS("-Wall") # Generate all warnings -#ADD_DEFINITIONS("-Wextra") # Generate even more extra warnings -#ADD_DEFINITIONS("-pedantic") # Be pedantic -#ADD_DEFINITIONS("-pedantic-errors") # Make pedantic warnings into errors +ADD_DEFINITIONS("-Wextra") # Generate even more extra warnings +# TODO Remove 'no-unused-parameter' after API implementation +ADD_DEFINITIONS("-Wno-unused-parameter") # Supress unused parameter warning +ADD_DEFINITIONS("-pedantic") # Be pedantic +ADD_DEFINITIONS("-pedantic-errors") # Make pedantic warnings into errors ADD_DEFINITIONS(-DPROJECT_SOURCE_DIR="${PROJECT_SOURCE_DIR}") IF("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") # Warn about documentation problems - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wdocumentation") + ADD_DEFINITIONS("-Wdocumentation") # Enable all diagnostics - #SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Weverything") + #ADD_DEFINITIONS("-Weverything") ENDIF() ## Subdirectories ############################################################## diff --git a/src/internal.h b/src/internal.h index 6aefaa8..074951b 100644 --- a/src/internal.h +++ b/src/internal.h @@ -66,7 +66,7 @@ struct yaca_key_simple_s struct yaca_key_s key; size_t bits; - char d[0]; + char d[]; }; /** -- 2.7.4