From 72833a0f34413ad54a44042e3f3f08a7e363c6f1 Mon Sep 17 00:00:00 2001 From: Mateusz Kulikowski Date: Mon, 11 Apr 2016 11:43:04 +0200 Subject: [PATCH 01/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 02/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 03/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 From dd9801ab8d32af0132c1b1d8c0814b121091d1a4 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Tue, 12 Apr 2016 13:30:02 +0200 Subject: [PATCH 04/16] Add YACA_ERROR_SIGNATURE_INVALID error code. Mentioned in the doxygen. Change-Id: Ieff9d6a8408c878b7ff9656f637382abab23f742 --- api/yaca/error.h | 3 ++- api/yaca/sign.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/api/yaca/error.h b/api/yaca/error.h index 9a192f4..e8d11ed 100644 --- a/api/yaca/error.h +++ b/api/yaca/error.h @@ -37,7 +37,8 @@ enum __yaca_error_code { YACA_ERROR_OPENSSL_FAILURE = -3, YACA_ERROR_NOT_SUPPORTED = -4, YACA_ERROR_TOO_BIG_ARGUMENT = -5, - YACA_ERROR_OUT_OF_MEMORY = -6 + YACA_ERROR_OUT_OF_MEMORY = -6, + YACA_ERROR_SIGNATURE_INVALID = -7 }; #ifdef __cplusplus diff --git a/api/yaca/sign.h b/api/yaca/sign.h index 0f0855e..217d15d 100644 --- a/api/yaca/sign.h +++ b/api/yaca/sign.h @@ -113,7 +113,7 @@ int yaca_verify_update(yaca_ctx_h ctx, * @param[in] mac_len Size of the MAC or the signature. * * @return 0 on success, negative on error (@see error.h). - * TODO: CRYTPO_ERROR_SIGNATURE_INVALID when verification fails. + * TODO: YACA_ERROR_SIGNATURE_INVALID when verification fails. */ int yaca_verify_final(yaca_ctx_h ctx, const char *mac, -- 2.7.4 From 4d688df05d74a6f2624902130faae9048f899208 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Tue, 12 Apr 2016 13:30:44 +0200 Subject: [PATCH 05/16] Add todo.txt file for global TODOs. Change-Id: I79d942960fa25b44095b6ea150d5bd1f408c8343 --- todo.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 todo.txt diff --git a/todo.txt b/todo.txt new file mode 100644 index 0000000..4f24242 --- /dev/null +++ b/todo.txt @@ -0,0 +1,3 @@ +Global: +- Rethink and possibly add verification of output buffer lengths. + In other words check whether the user won't cause a buffer overflow. -- 2.7.4 From 0af4e6ef1b64389a57475fee28f0d1e39d9e805a Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Tue, 12 Apr 2016 13:33:19 +0200 Subject: [PATCH 06/16] Get rid of EVP_MD from digest struct, it's redudant. Change-Id: I52d84125d4b0f2ab1face439477efcc82ee0a0fe --- src/digest.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/digest.c b/src/digest.c index 4cc0ceb..bd3f62f 100644 --- a/src/digest.c +++ b/src/digest.c @@ -32,7 +32,6 @@ struct yaca_digest_ctx_s { struct yaca_ctx_s ctx; - const EVP_MD *md; EVP_MD_CTX *mdctx; }; @@ -57,7 +56,7 @@ static int get_digest_output_length(const yaca_ctx_h ctx, size_t input_len) if (c == NULL) return YACA_ERROR_INVALID_ARGUMENT; - return EVP_MD_size(c->md); + return EVP_MD_CTX_size(c->mdctx); } static void destroy_digest_context(yaca_ctx_h ctx) @@ -117,6 +116,7 @@ API int yaca_digest_init(yaca_ctx_h *ctx, yaca_digest_algo_e algo) { int ret; struct yaca_digest_ctx_s *nc = NULL; + const EVP_MD *md; if (ctx == NULL) return YACA_ERROR_INVALID_ARGUMENT; @@ -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 = digest_get_algorithm(algo, &nc->md); + ret = digest_get_algorithm(algo, &md); if (ret < 0) goto free; @@ -139,7 +139,7 @@ API int yaca_digest_init(yaca_ctx_h *ctx, yaca_digest_algo_e algo) goto free; } - ret = EVP_DigestInit(nc->mdctx, nc->md); + ret = EVP_DigestInit(nc->mdctx, md); if (ret != 1) { ret = YACA_ERROR_OPENSSL_FAILURE; goto ctx; -- 2.7.4 From 8eb62230e8f7849a09c81283f0fd56ce77d72046 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Tue, 12 Apr 2016 13:34:04 +0200 Subject: [PATCH 07/16] Small cosmetic change in digest.c to line it up with the style of the rest of the code. Change-Id: Ib22750311254ffaaa0f241191f9a9fdeed1a00b7 --- src/digest.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/digest.c b/src/digest.c index bd3f62f..93a2535 100644 --- a/src/digest.c +++ b/src/digest.c @@ -147,15 +147,12 @@ API int yaca_digest_init(yaca_ctx_h *ctx, yaca_digest_algo_e algo) *ctx = (yaca_ctx_h)nc; - ret = 0; + return 0; ctx: - if (ret != 0) - EVP_MD_CTX_destroy(nc->mdctx); + EVP_MD_CTX_destroy(nc->mdctx); free: - if (ret != 0) - yaca_free(nc); - + yaca_free(nc); return ret; } -- 2.7.4 From d475db4315e73f0b5a6875c79f4087d92f5da895 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Tue, 12 Apr 2016 13:34:44 +0200 Subject: [PATCH 08/16] Implement getting the bits of an evp type key. Change-Id: Ibbd62e146bcfc7ecaa999a694416db2488e14052 --- src/key.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/key.c b/src/key.c index 78dd5c8..6ba3c9e 100644 --- a/src/key.c +++ b/src/key.c @@ -104,8 +104,16 @@ API int yaca_key_get_length(const yaca_key_h key) } if (evp_key != NULL) { + int ret; + evp_key_sanity_check(evp_key); - return YACA_ERROR_NOT_IMPLEMENTED; + + // TODO: handle ECC keys when they're implemented + ret = EVP_PKEY_bits(evp_key->evp); + if (ret <= 0) + return YACA_ERROR_OPENSSL_FAILURE; + + return ret; } return YACA_ERROR_INVALID_ARGUMENT; -- 2.7.4 From dbffca578cb0f37f323ca093512b7de20bb104bf Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Tue, 12 Apr 2016 14:54:01 +0200 Subject: [PATCH 09/16] Remove unused function pointer, no need to do that for keys. Change-Id: I1b856243bc42a09783cadfe42b402f9c8dc144f0 --- src/internal.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/internal.h b/src/internal.h index 074951b..491ec2d 100644 --- a/src/internal.h +++ b/src/internal.h @@ -51,8 +51,6 @@ struct yaca_ctx_s struct yaca_key_s { yaca_key_type_e type; - - int (*get_key_length)(const struct yaca_key_s *key); }; /** -- 2.7.4 From 6f066fc11fb5daa91f5e31594dca5d2b9c9d54d8 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Tue, 12 Apr 2016 13:42:30 +0200 Subject: [PATCH 10/16] Add SIGN context to context types. Change-Id: If61017092a29d5b50c6036b825492a7760e87cd6 --- src/internal.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/internal.h b/src/internal.h index 491ec2d..deeff97 100644 --- a/src/internal.h +++ b/src/internal.h @@ -34,7 +34,8 @@ enum yaca_ctx_type_e { YACA_CTX_INVALID = 0, - YACA_CTX_DIGEST + YACA_CTX_DIGEST, + YACA_CTX_SIGN }; /* Base structure for crypto contexts - to be inherited */ -- 2.7.4 From 621c2df6d2005b367b5eb2e5100ead43394708ec Mon Sep 17 00:00:00 2001 From: Mateusz Kulikowski Date: Wed, 13 Apr 2016 14:44:40 +0200 Subject: [PATCH 11/16] examples: Add LOREM*_SIZE Add macros containing sizes of lorem* strings. Change-Id: I2514f9fc03d55561530fac9ec856f404f9aa987b Signed-off-by: Mateusz Kulikowski --- examples/lorem.c | 10 ++++++---- examples/lorem.h | 18 ++++++++++++++---- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/examples/lorem.c b/examples/lorem.c index ac6955f..d6f9f42 100644 --- a/examples/lorem.c +++ b/examples/lorem.c @@ -21,12 +21,14 @@ * @brief Lorem Ipsum */ -const char *lorem8 = "Lorem i"; -const char *lorem16 = "Lorem ipsum dol"; -const char *lorem1024 = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec non dolor tincidunt, vehicula erat non, pulvinar nisl. Suspendisse gravida commodo hendrerit. Sed ex magna, aliquet malesuada lectus ut, porttitor tincidunt ante. Nulla facilisi. Morbi nec scelerisque risus. Sed a gravida sapien. Cras sed neque bibendum, dapibus lectus sed, porta nulla. Morbi tristique velit lacus, at luctus turpis mollis sed. Nam quis sapien eu magna cursus venenatis. Phasellus et vestibulum urna, non pellentesque ex. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam pretium aliquam porta.\ +#include "lorem.h" + +const char lorem8[LOREM8_SIZE] = "Lorem i"; +const char lorem16[LOREM16_SIZE] = "Lorem ipsum dol"; +const char lorem1024[LOREM1024_SIZE] = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec non dolor tincidunt, vehicula erat non, pulvinar nisl. Suspendisse gravida commodo hendrerit. Sed ex magna, aliquet malesuada lectus ut, porttitor tincidunt ante. Nulla facilisi. Morbi nec scelerisque risus. Sed a gravida sapien. Cras sed neque bibendum, dapibus lectus sed, porta nulla. Morbi tristique velit lacus, at luctus turpis mollis sed. Nam quis sapien eu magna cursus venenatis. Phasellus et vestibulum urna, non pellentesque ex. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam pretium aliquam porta.\ Morbi magna metus, commodo in fermentum id, mattis pretium mauris. Donec sed rhoncus justo. Duis fringilla sem quis velit dignissim bibendum. Sed porta efficitur ipsum, in dignissim magna molestie eu. Sed elementum maximus risus. Quisque cursus urna lectus, sit amet fringilla purus tempor eu. Praesent tincidunt dolor sit amet dolor vulputate, et molestie tellus euismod. Proin suscipit dictum amet."; -const char *lorem4096 = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus congue semper ipsum, ac convallis magna rhoncus sit amet. Donec pellentesque maximus convallis. Mauris ut egestas sem. Maecenas efficitur suscipit auctor. Nunc malesuada laoreet porttitor. Donec gravida tortor nisi, in mattis lectus porta ut. Integer vehicula eros et tellus placerat, nec fermentum justo aliquet.\ +const char lorem4096[LOREM4096_SIZE] = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus congue semper ipsum, ac convallis magna rhoncus sit amet. Donec pellentesque maximus convallis. Mauris ut egestas sem. Maecenas efficitur suscipit auctor. Nunc malesuada laoreet porttitor. Donec gravida tortor nisi, in mattis lectus porta ut. Integer vehicula eros et tellus placerat, nec fermentum justo aliquet.\ Maecenas metus massa, ultrices et ultricies sed, imperdiet nec dolor. Nam eget massa eros. Proin vitae laoreet metus, at scelerisque massa. Nullam convallis dolor id nisl iaculis, a gravida risus pretium. Proin non nunc eget nibh fermentum dignissim. Nullam tristique, odio eget rutrum sagittis, tortor purus cursus nunc, nec iaculis quam nunc ac metus. Cras ut tortor a eros porta vehicula non at lectus. Aliquam volutpat quis nisi ut mattis. Curabitur semper vehicula ultrices. Aenean cursus laoreet venenatis. Aenean vulputate, nisl id facilisis fringilla, neque velit posuere libero, et viverra tortor felis vitae urna. Sed in congue nunc. Fusce molestie tempor pharetra. Cras sodales pulvinar nunc non sollicitudin.\ Maecenas vehicula metus ac tristique ultricies. Suspendisse potenti. Pellentesque suscipit egestas augue, sed dictum orci. Pellentesque eu lorem ultricies, vestibulum est in, bibendum turpis. Proin placerat tincidunt metus, eget volutpat dolor. Pellentesque varius leo eget velit lobortis, sit amet congue orci bibendum. Aliquam vitae posuere lorem. Donec sed convallis diam. Quisque aliquam interdum purus, eu ornare ex ullamcorper iaculis. In sit amet nisl eu nisl ultricies dapibus. Aenean finibus efficitur elit ut sodales. Nam sit amet auctor sem, eu iaculis nunc. Vivamus mattis arcu a viverra faucibus. In dignissim, nisi sit amet consectetur tempus, lorem dui fringilla augue, sit amet lacinia lectus sapien efficitur odio.\ Nullam et egestas enim. Nam sit amet mi malesuada, dapibus felis quis, viverra mauris. Ut quis enim eu neque porta vehicula. Etiam ullamcorper vitae turpis vehicula blandit. Maecenas blandit tristique semper. Aliquam at sagittis enim. Donec quis molestie urna. Duis ut urna blandit, pellentesque magna ultrices, dignissim mi. Morbi fermentum ex massa, ut facilisis est tincidunt vel. Nam sed erat in lacus molestie mattis quis ut leo. Phasellus tempus elit urna, eget sagittis purus volutpat sed. Suspendisse aliquam, sem vel gravida lobortis, tortor orci ornare nisi, sed mollis ligula sem nec risus. In a ex nibh. Praesent odio est, molestie sed vestibulum id, varius sit amet lectus. Donec vel diam efficitur, tristique ligula a, aliquet felis. Nullam sit amet neque tellus.\ diff --git a/examples/lorem.h b/examples/lorem.h index 1b7ceb5..1b02d19 100644 --- a/examples/lorem.h +++ b/examples/lorem.h @@ -24,12 +24,22 @@ #ifndef LOREM_H #define LOREM_H +#include + /** Test strings, sizes include null-termination */ -extern const char *lorem8; -extern const char *lorem16; -extern const char *lorem1024; -extern const char *lorem4096; +extern const char lorem8[]; +extern const char lorem16[]; +extern const char lorem1024[]; +extern const char lorem4096[]; + +/** + * Sizes of test strings + */ +#define LOREM8_SIZE ((size_t)8) +#define LOREM16_SIZE ((size_t)16) +#define LOREM1024_SIZE ((size_t)1024) +#define LOREM4096_SIZE ((size_t)4096) #endif -- 2.7.4 From 7979a7584e6e0898ec68dddde6d495edad6db5c8 Mon Sep 17 00:00:00 2001 From: Mateusz Kulikowski Date: Wed, 13 Apr 2016 14:45:16 +0200 Subject: [PATCH 12/16] crypto.h: rename yaca_get_iv_length() to yaca_get_iv_bits() Function returns IV length in bits - rename it to avoid confusion. Change-Id: I58f565e1ca96321856f099d55ec456f23be1dbe0 Signed-off-by: Mateusz Kulikowski --- api/yaca/crypto.h | 10 +++++----- src/crypto.c | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/api/yaca/crypto.h b/api/yaca/crypto.h index 66d77e6..1b9feab 100644 --- a/api/yaca/crypto.h +++ b/api/yaca/crypto.h @@ -163,17 +163,17 @@ int yaca_get_output_length(const yaca_ctx_h ctx, size_t input_len); #define yaca_get_block_length(ctxa) yaca_get_output_length((ctxa), 0) /** - * @brief yaca_get_iv_length Returns the recomended/default length of the IV for a given encryption configuration. + * @brief yaca_get_iv_bits 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_bits Key length in bits (@see crypto_key_len_e). * - * @return negative on error (@see error.h) or the IV length. + * @return negative on error (@see error.h) or the IV length in bits. */ -int yaca_get_iv_length(yaca_enc_algo_e algo, - yaca_block_cipher_mode_e bcm, - size_t key_bits); +int yaca_get_iv_bits(yaca_enc_algo_e algo, + yaca_block_cipher_mode_e bcm, + size_t key_bits); /**@}*/ diff --git a/src/crypto.c b/src/crypto.c index af73404..9081bcf 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -108,9 +108,9 @@ API int yaca_get_output_length(const yaca_ctx_h ctx, size_t input_len) return ctx->get_output_length(ctx, input_len); } -API int yaca_get_iv_length(yaca_enc_algo_e algo, - yaca_block_cipher_mode_e bcm, - size_t key_bits) +API int yaca_get_iv_bits(yaca_enc_algo_e algo, + yaca_block_cipher_mode_e bcm, + size_t key_bits) { return YACA_ERROR_NOT_IMPLEMENTED; } -- 2.7.4 From 144545c77f8b73340d9f684a8ccea404692a777f Mon Sep 17 00:00:00 2001 From: Mateusz Kulikowski Date: Mon, 11 Apr 2016 11:58:52 +0200 Subject: [PATCH 13/16] Encrypt example update - Handle outputs allocation properly - Calculate IV lengths - Generate IV properly Change-Id: I3ae9c15dac9fa36bb308846fc4c33c61296ca819 Signed-off-by: Mateusz Kulikowski --- examples/encrypt.c | 134 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 89 insertions(+), 45 deletions(-) diff --git a/examples/encrypt.c b/examples/encrypt.c index 8ca1bc1..f428713 100644 --- a/examples/encrypt.c +++ b/examples/encrypt.c @@ -33,6 +33,9 @@ // Symmetric encryption using simple API void encrypt_simple(void) { + const yaca_enc_algo_e algo = YACA_ENC_AES; + const yaca_block_cipher_mode_e bcm = YACA_BCM_CBC; + const size_t key_bits = YACA_KEY_256BIT; int ret; yaca_key_h key = YACA_KEY_NULL; yaca_key_h iv = YACA_KEY_NULL; @@ -40,30 +43,35 @@ void encrypt_simple(void) char *dec_data = NULL; size_t enc_len; size_t dec_len; + int iv_bits; - printf("Plain data (16 of %zu bytes): %.16s\n", (size_t)1024, lorem1024); + printf("Simple Encrypt\nPlain data (16 of %zu bytes): %.16s\n", + LOREM1024_SIZE, lorem1024); - ret = yaca_key_derive_pbkdf2("foo bar", "123456789", 10, - 1000, YACA_DIGEST_SHA256, - YACA_KEY_256BIT, &key); + ret = yaca_key_derive_pbkdf2("foo bar", "123456789", 10, 1000, + YACA_DIGEST_SHA256, key_bits, &key); if (ret) return; - ret = yaca_key_gen(&iv, YACA_KEY_TYPE_IV, YACA_KEY_IV_256BIT); - if (ret) - goto exit; + iv_bits = yaca_get_iv_bits(algo, bcm, key_bits); + if (iv_bits < 0) + return; + + if (iv_bits > 0) { + ret = yaca_key_gen(&iv, YACA_KEY_TYPE_IV, iv_bits); + if (ret) + goto exit; + } - ret = yaca_encrypt(YACA_ENC_AES, YACA_BCM_CBC, - key, iv, lorem1024, 1024, &enc_data, &enc_len); + ret = yaca_encrypt(algo, bcm, key, iv, lorem1024, LOREM1024_SIZE, + &enc_data, &enc_len); if (ret) goto exit; dump_hex(enc_data, 16, "Encrypted data (16 of %zu bytes): ", enc_len); - ret = yaca_decrypt(YACA_ENC_AES, YACA_BCM_CBC, - key, iv, - enc_data, enc_len, - &dec_data, &dec_len); + ret = yaca_decrypt(algo, bcm, key, iv, enc_data, enc_len, &dec_data, + &dec_len); if (ret < 0) goto exit; @@ -81,6 +89,9 @@ exit: // Symmetric encryption using advanced API void encrypt_advanced(void) { + const yaca_enc_algo_e algo = YACA_ENC_AES; + const yaca_block_cipher_mode_e bcm = YACA_BCM_CBC; + const size_t key_bits = YACA_KEY_256BIT; int ret; yaca_ctx_h ctx; yaca_key_h key = YACA_KEY_NULL; @@ -89,86 +100,113 @@ void encrypt_advanced(void) char *dec = NULL; size_t enc_size; size_t dec_size; + int iv_bits; - printf("Plain data (16 of %zu bytes): %.16s\n", (size_t)4096, lorem1024); + printf("Advanced Encrypt\nPlain data (16 of %zu bytes): %.16s\n", + LOREM4096_SIZE, lorem4096); /// Key generation - ret = yaca_key_derive_pbkdf2("foo bar", "123456789", 10, - 1000, YACA_DIGEST_SHA256, - YACA_KEY_256BIT, &key); + ret = yaca_key_derive_pbkdf2("foo bar", "123456789", 10, 1000, + YACA_DIGEST_SHA256, key_bits, &key); if (ret) return; - ret = yaca_key_gen(&iv, YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_IV_256BIT); - if (ret) + iv_bits = yaca_get_iv_bits(algo, bcm, key_bits); + if (iv_bits < 0) goto ex_key; + if (iv_bits > 0) { + ret = yaca_key_gen(&iv, YACA_KEY_TYPE_IV, iv_bits); + if (ret) + goto ex_key; + } + /// Encryption { - ret = yaca_encrypt_init(&ctx, YACA_ENC_AES, YACA_BCM_CBC, - key, iv); + size_t block_len; + size_t output_len; + size_t out_size; + size_t rem; + + ret = yaca_encrypt_init(&ctx, algo, bcm, key, iv); if (ret) goto ex_iv; - ret = yaca_encrypt_update(ctx, lorem4096, 4096, NULL, &enc_size); - if (ret != 42) - goto ex_ctx;// TODO: what error code? - ret = yaca_get_block_length(ctx); if (ret < 0) goto ex_ctx; - enc_size += ret ; // Add block size for finalize + block_len = ret; + + ret = yaca_get_output_length(ctx, LOREM4096_SIZE); + if (ret < 0) + goto ex_ctx; + + output_len = ret; + + /* Calculate max output: size of update + final chunks */ + enc_size = output_len + block_len; enc = yaca_malloc(enc_size); if (enc == NULL) goto ex_ctx; - size_t out_size = enc_size; - ret = yaca_encrypt_update(ctx, lorem4096, 4096, enc, &out_size); + out_size = enc_size; + ret = yaca_encrypt_update(ctx, lorem4096, LOREM4096_SIZE, enc, + &out_size); if (ret < 0) goto ex_of; - size_t rem = enc_size - out_size; + rem = enc_size - out_size; ret = yaca_encrypt_final(ctx, enc + out_size, &rem); if (ret < 0) goto ex_of; enc_size = rem + out_size; - dump_hex(enc, 16, "Encrypted data (16 of %zu bytes): ", enc_size); + dump_hex(enc, 16, "Encrypted data (16 of %zu bytes): ", + enc_size); yaca_ctx_free(ctx); // TODO: perhaps it should not return value } /// Decryption { - ret = yaca_decrypt_init(&ctx, YACA_ENC_AES, YACA_BCM_CBC, - key, iv); + size_t block_len; + size_t output_len; + size_t out_size; + size_t rem; + + ret = yaca_decrypt_init(&ctx, algo, bcm, key, iv); if (ret < 0) { - yaca_free(enc); - goto ex_iv; + ctx = YACA_CTX_NULL; + goto ex_of; } - ret = yaca_decrypt_update(ctx, enc, enc_size, NULL, &dec_size); - if (ret != 42) - goto ex_of; // TODO: what error code? - ret = yaca_get_block_length(ctx); if (ret < 0) goto ex_of; - dec_size += ret; // Add block size for finalize + block_len = ret; + + ret = yaca_get_output_length(ctx, LOREM4096_SIZE); + if (ret < 0) + goto ex_ctx; + + output_len = ret; + + /* Calculate max output: size of update + final chunks */ + dec_size = output_len + block_len; dec = yaca_malloc(dec_size); if (dec == NULL) goto ex_of; - size_t out_size = dec_size; + out_size = dec_size; ret = yaca_decrypt_update(ctx, enc, enc_size, dec, &out_size); if (ret < 0) goto ex_in; - size_t rem = dec_size - out_size; + rem = dec_size - out_size; ret = yaca_encrypt_final(ctx, dec + out_size, &rem); if (ret < 0) goto ex_in; @@ -214,6 +252,9 @@ void encrypt_seal(void) /// Encrypt a.k.a. seal { + size_t out_size; + size_t rem; + ret = yaca_seal_init(&ctx, key_pub, YACA_ENC_AES, YACA_BCM_CBC, &aes_key, &iv); @@ -234,12 +275,12 @@ void encrypt_seal(void) goto ex_ak; // Seal and finalize - size_t out_size = enc_size; + out_size = enc_size; ret = yaca_seal_update(ctx, lorem4096, 4096, enc, &out_size); if (ret < 0) goto ex_of; - size_t rem = enc_size - out_size; + rem = enc_size - out_size; ret = yaca_seal_final(ctx, enc + out_size, &rem); if (ret < 0) goto ex_of; @@ -253,6 +294,9 @@ void encrypt_seal(void) /// Decrypt a.k.a. open { + size_t out_size; + size_t rem; + ret = yaca_open_init(&ctx, key_priv, YACA_ENC_AES, YACA_BCM_CBC, aes_key, iv); @@ -275,12 +319,12 @@ void encrypt_seal(void) goto ex_of; // Seal and finalize - size_t out_size = enc_size; + out_size = enc_size; ret = yaca_open_update(ctx, enc, enc_size, dec, &out_size); if (ret < 0) goto ex_in; - size_t rem = dec_size - out_size; + rem = dec_size - out_size; ret = yaca_open_final(ctx, dec + out_size, &rem); if (ret < 0) goto ex_in; -- 2.7.4 From 455ddca22cb754e2a344b506a2fbbd28b0211c5d Mon Sep 17 00:00:00 2001 From: Mateusz Kulikowski Date: Mon, 11 Apr 2016 12:40:18 +0200 Subject: [PATCH 14/16] simple: Handle encrypt/decrypt block sizes properly - Calculate output block sizes properly - Resize output allocations to size output Change-Id: I58cc4530f9b832375c20c79c9883910adaaccc67 Signed-off-by: Mateusz Kulikowski --- src/simple.c | 62 ++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 16 deletions(-) diff --git a/src/simple.c b/src/simple.c index ce1d5f3..ff7f19e 100644 --- a/src/simple.c +++ b/src/simple.c @@ -90,6 +90,7 @@ API int yaca_encrypt(yaca_enc_algo_e algo, yaca_ctx_h ctx; int ret; char *lcipher; + char *rcipher; size_t out_len, lcipher_len, written; if (plain == NULL || plain_len == 0 || cipher == NULL || cipher_len == NULL || @@ -100,21 +101,28 @@ API int yaca_encrypt(yaca_enc_algo_e algo, return YACA_ERROR_TOO_BIG_ARGUMENT; ret = yaca_encrypt_init(&ctx, algo, bcm, sym_key, iv); - if (ret < 0) + if (ret != 0) return ret; - ret = yaca_get_output_length(ctx, plain_len); - if (ret < 0) + ret = yaca_get_block_length(ctx); + if (ret <= 0) goto err; lcipher_len = ret; + + ret = yaca_get_output_length(ctx, plain_len); + if (ret <= 0) + goto err; + + lcipher_len += ret; + lcipher = yaca_malloc(lcipher_len); if (lcipher == NULL) goto err; out_len = lcipher_len; ret = yaca_encrypt_update(ctx, plain, plain_len, lcipher, &out_len); - if (ret < 0) + if (ret != 0) goto err_free; assert (out_len <= lcipher_len); @@ -122,15 +130,22 @@ API int yaca_encrypt(yaca_enc_algo_e algo, written = out_len; out_len = lcipher_len - written; ret = yaca_encrypt_final(ctx, lcipher + written, &out_len); - if (ret < 0) + if (ret != 0) goto err_free; - assert (out_len + written == lcipher_len); + written += out_len; + assert (written <= lcipher_len); + + rcipher = yaca_realloc(lcipher, written); + if (rcipher == NULL) { + ret = YACA_ERROR_OUT_OF_MEMORY; + goto err_free; + } yaca_ctx_free(ctx); - *cipher = lcipher; - *cipher_len = lcipher_len; + *cipher = rcipher; + *cipher_len = written; return 0; err_free: @@ -152,6 +167,7 @@ API int yaca_decrypt(yaca_enc_algo_e algo, yaca_ctx_h ctx; int ret; char *lplain; + char *rplain; size_t out_len, lplain_len, written; if (cipher == NULL || cipher_len == 0 || plain == NULL || plain_len == NULL || @@ -162,21 +178,28 @@ API int yaca_decrypt(yaca_enc_algo_e algo, return YACA_ERROR_TOO_BIG_ARGUMENT; ret = yaca_decrypt_init(&ctx, algo, bcm, sym_key, iv); - if (ret < 0) + if (ret != 0) return ret; - ret = yaca_get_output_length(ctx, cipher_len); - if (ret < 0) + ret = yaca_get_block_length(ctx); + if (ret <= 0) goto err; lplain_len = ret; + + ret = yaca_get_output_length(ctx, cipher_len); + if (ret <= 0) + goto err; + + lplain_len += ret; + lplain = yaca_malloc(lplain_len); if (!lplain) goto err; out_len = lplain_len; ret = yaca_decrypt_update(ctx, cipher, cipher_len, lplain, &out_len); - if (ret < 0) + if (ret != 0) goto err_free; assert(out_len <= lplain_len); @@ -184,15 +207,22 @@ API int yaca_decrypt(yaca_enc_algo_e algo, written = out_len; out_len = lplain_len - written; ret = yaca_decrypt_final(ctx, lplain + written, &out_len); - if (ret < 0) + if (ret != 0) goto err_free; - assert(out_len + written == lplain_len); + written += out_len; + assert(written <= lplain_len); + + rplain = yaca_realloc(lplain, written); + if (rplain == NULL) { + ret = YACA_ERROR_OUT_OF_MEMORY; + goto err_free; + } yaca_ctx_free(ctx); - *plain = lplain; - *plain_len = lplain_len; + *plain = rplain; + *plain_len = written; return 0; err_free: -- 2.7.4 From c06a90476453190abfe4b143094c91719a0ce9e0 Mon Sep 17 00:00:00 2001 From: Mateusz Kulikowski Date: Mon, 11 Apr 2016 15:27:21 +0200 Subject: [PATCH 15/16] internal.h: add YACA_CTX_ENCRYPT It is context for encryption Change-Id: Icb8ebbb9804edca48cab3d6523a9e27c3ab30fe1 Signed-off-by: Mateusz Kulikowski --- src/internal.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/internal.h b/src/internal.h index deeff97..504fb6d 100644 --- a/src/internal.h +++ b/src/internal.h @@ -35,7 +35,8 @@ enum yaca_ctx_type_e { YACA_CTX_INVALID = 0, YACA_CTX_DIGEST, - YACA_CTX_SIGN + YACA_CTX_SIGN, + YACA_CTX_ENCRYPT, }; /* Base structure for crypto contexts - to be inherited */ -- 2.7.4 From 9b3d768ceec9e8f051f6f140361a82c231b6a063 Mon Sep 17 00:00:00 2001 From: Mateusz Kulikowski Date: Mon, 11 Apr 2016 15:31:50 +0200 Subject: [PATCH 16/16] encrypt: add get_symmetric_algorithm Implement function to map yaca algorithm enums to EVP_CIPHER. It is currently not very fast, and doesn't handle all algorithms/modes supported by yaca. Change-Id: I34c9a78044561b7fdcdc9e23632e45ff745e7f34 Signed-off-by: Mateusz Kulikowski --- src/encrypt.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/src/encrypt.c b/src/encrypt.c index ca8fa1d..596a1a4 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -20,12 +20,90 @@ #include #include +#include #include #include #include "internal.h" +static const char *symmetric_algo_to_str(yaca_enc_algo_e algo) +{ + switch(algo) + { + case YACA_ENC_AES: + return "aes"; + case YACA_ENC_UNSAFE_DES: + return "des"; + case YACA_ENC_UNSAFE_RC2: + return "rc2"; + case YACA_ENC_UNSAFE_RC4: + return "rc4"; + case YACA_ENC_CAST5: + return "cast5"; + + case YACA_ENC_UNSAFE_3DES_2TDEA: // TODO: add 3des/2tdea support + case YACA_ENC_3DES_3TDEA: // TODO: add 3des/3tdea support + case YACA_ENC_UNSAFE_SKIPJACK: // TODO: add skipjack implementation + default: + return NULL; + } +} + +static const char *bcm_to_str(yaca_block_cipher_mode_e bcm) +{ + switch (bcm) { + case YACA_BCM_ECB: + return "ecb"; + case YACA_BCM_CBC: + return "cbc"; + case YACA_BCM_CTR: + return "ctr"; + case YACA_BCM_GCM: + return "gcm"; + case YACA_BCM_CFB: + return "cfb"; + case YACA_BCM_OFB: + return "ofb"; + case YACA_BCM_OCB: + return "ocb"; + case YACA_BCM_CCM: + return "ccm"; + default: + return NULL; + } +} + +int get_symmetric_algorithm(yaca_enc_algo_e algo, + yaca_block_cipher_mode_e bcm, + unsigned key_bits, + const EVP_CIPHER **cipher) +{ + char cipher_name[32]; + const char *algo_name = symmetric_algo_to_str(algo); + const char *bcm_name = bcm_to_str(bcm); + const EVP_CIPHER *lcipher; + int ret; + + if (algo_name == NULL || bcm_name == NULL || key_bits == 0 || + cipher == NULL) + return YACA_ERROR_INVALID_ARGUMENT; + + ret = snprintf(cipher_name, sizeof(cipher_name), "%s-%d-%s", algo_name, + key_bits, bcm_name); + if (ret < 0) + return YACA_ERROR_INVALID_ARGUMENT; + if ((unsigned)ret >= sizeof(cipher_name)) // output was truncated + return YACA_ERROR_INVALID_ARGUMENT; + + lcipher = EVP_get_cipherbyname(cipher_name); + if (lcipher == NULL) + return YACA_ERROR_OPENSSL_FAILURE; // TODO: yaca_get_error_code_from_openssl(ret); + + *cipher = lcipher; + return 0; +} + API int yaca_encrypt_init(yaca_ctx_h *ctx, yaca_enc_algo_e algo, yaca_block_cipher_mode_e bcm, -- 2.7.4