From 59b774dcfe65ac398e56813bc4af774fcbbdc716 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Thu, 21 Apr 2016 16:06:38 +0200 Subject: [PATCH 01/16] yaca_open_init() needs key length to generate EVP_CIPHER Change-Id: I5d12ca2ac41c54a6a73844033c9ab6a0118b954f --- api/yaca/seal.h | 14 ++++++++------ examples/seal.c | 2 +- src/seal.c | 1 + 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/api/yaca/seal.h b/api/yaca/seal.h index a080247..3467291 100644 --- a/api/yaca/seal.h +++ b/api/yaca/seal.h @@ -97,12 +97,13 @@ int yaca_seal_final(yaca_ctx_h ctx, /** * @brief yaca_open_init Initializes an asymmetric decryption context. * - * @param[out] ctx Newly created context. Must be freed by @see yaca_ctx_free. - * @param[in] prv_key Private key, part of the pair that was used for the encryption. - * @param[in] algo Symmetric algorithm that was used for the encryption. - * @param[in] bcm Block chaining mode for the symmetric algorithm. - * @param[in] sym_key Symmetric key, encrypted with the public key, that was used to encrypt the data. - * @param[in] iv Initialization vector that was used for the encryption. + * @param[out] ctx Newly created context. Must be freed by @see yaca_ctx_free. + * @param[in] prv_key Private key, part of the pair that was used for the encryption. + * @param[in] algo Symmetric algorithm that was used for the encryption. + * @param[in] bcm Block chaining mode for the symmetric algorithm. + * @param[in] sym_key_bits Symmetric key length (in bits) that was used for the encryption. + * @param[in] sym_key Symmetric key, encrypted with the public key, that was used to encrypt the data. + * @param[in] iv Initialization vector that was used for the encryption. * * @return 0 on success, negative on error (@see error.h). */ @@ -110,6 +111,7 @@ int yaca_open_init(yaca_ctx_h *ctx, const yaca_key_h prv_key, yaca_enc_algo_e algo, yaca_block_cipher_mode_e bcm, + yaca_key_bits_e sym_key_bits, const yaca_key_h sym_key, const yaca_key_h iv); diff --git a/examples/seal.c b/examples/seal.c index 985f5dc..c913b48 100644 --- a/examples/seal.c +++ b/examples/seal.c @@ -100,7 +100,7 @@ void encrypt_seal(void) size_t rem; ret = yaca_open_init(&ctx, key_priv, - YACA_ENC_AES, YACA_BCM_CBC, + YACA_ENC_AES, YACA_BCM_CBC, YACA_KEY_192BIT, aes_key, iv); if (ret < 0) { yaca_free(enc); diff --git a/src/seal.c b/src/seal.c index 7b9308a..cc4b1c9 100644 --- a/src/seal.c +++ b/src/seal.c @@ -61,6 +61,7 @@ API int yaca_open_init(yaca_ctx_h *ctx, const yaca_key_h prv_key, yaca_enc_algo_e algo, yaca_block_cipher_mode_e bcm, + yaca_key_bits_e sym_key_bits, const yaca_key_h sym_key, const yaca_key_h iv) { -- 2.7.4 From 15368c9cbb29f4d3472956b34505655c023d90c1 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Thu, 21 Apr 2016 13:09:18 +0200 Subject: [PATCH 02/16] Seal/Open implementation. Change-Id: I8c89eb8117158440fb6bd5ab8a6875ca29755093 --- api/yaca/key.h | 4 +- src/encrypt.c | 14 +- src/internal.h | 6 + src/key.c | 2 +- src/seal.c | 404 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 5 files changed, 390 insertions(+), 40 deletions(-) diff --git a/api/yaca/key.h b/api/yaca/key.h index b479867..114b02c 100644 --- a/api/yaca/key.h +++ b/api/yaca/key.h @@ -44,13 +44,13 @@ extern "C" { // TODO: We need a way to import keys encrypted with hw (or other) keys. New function like yaca_key_load or sth?? /** - * @brief yaca_key_get_length Get key's length. + * @brief yaca_key_get_bits Get key's length (in bits). * * @param[in] key Key which length we return. * * @return negative on error (@see error.h) or key length (in bits). */ -int yaca_key_get_length(const yaca_key_h key); +int yaca_key_get_bits(const yaca_key_h key); /** * @brief yaca_key_import Imports a key from the arbitrary format. diff --git a/src/encrypt.c b/src/encrypt.c index a18a05c..3fee076 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -134,9 +134,9 @@ static const char *bcm_to_str(yaca_block_cipher_mode_e bcm) } } -int get_encrypt_algorithm(yaca_enc_algo_e algo, +int encrypt_get_algorithm(yaca_enc_algo_e algo, yaca_block_cipher_mode_e bcm, - unsigned key_bits, + size_t key_bits, const EVP_CIPHER **cipher) { char cipher_name[32]; @@ -149,7 +149,7 @@ int get_encrypt_algorithm(yaca_enc_algo_e algo, cipher == NULL) return YACA_ERROR_INVALID_ARGUMENT; - ret = snprintf(cipher_name, sizeof(cipher_name), "%s-%d-%s", algo_name, + ret = snprintf(cipher_name, sizeof(cipher_name), "%s-%zu-%s", algo_name, key_bits, bcm_name); if (ret < 0) return YACA_ERROR_INVALID_ARGUMENT; @@ -199,12 +199,12 @@ static int encrypt_init(yaca_ctx_h *ctx, nc->op_type = op_type; // TODO: handling of algorithms with variable key length - ret = yaca_key_get_length(sym_key); + ret = yaca_key_get_bits(sym_key); if (ret < 0) goto err_free; key_bits = ret; - ret = get_encrypt_algorithm(algo, bcm, key_bits, &cipher); + ret = encrypt_get_algorithm(algo, bcm, key_bits, &cipher); if (ret != 0) goto err_free; @@ -228,7 +228,7 @@ static int encrypt_init(yaca_ctx_h *ctx, } // TODO: handling of algorithms with variable IV length - if (iv_bits != yaca_key_get_length(iv)) { /* IV length doesn't match cipher */ + if (iv_bits != yaca_key_get_bits(iv)) { /* IV length doesn't match cipher */ ret = YACA_ERROR_INVALID_ARGUMENT; goto err_free; } @@ -355,7 +355,7 @@ API int yaca_get_iv_bits(yaca_enc_algo_e algo, const EVP_CIPHER *cipher; int ret; - ret = get_encrypt_algorithm(algo, bcm, key_bits, &cipher); + ret = encrypt_get_algorithm(algo, bcm, key_bits, &cipher); if (ret < 0) return ret; diff --git a/src/internal.h b/src/internal.h index 2b5dc9f..5bff4f1 100644 --- a/src/internal.h +++ b/src/internal.h @@ -37,6 +37,7 @@ enum yaca_ctx_type_e YACA_CTX_DIGEST, YACA_CTX_SIGN, YACA_CTX_ENCRYPT, + YACA_CTX_SEAL }; /* Base structure for crypto contexts - to be inherited */ @@ -91,6 +92,11 @@ struct yaca_key_evp_s int digest_get_algorithm(yaca_digest_algo_e algo, const EVP_MD **md); +int encrypt_get_algorithm(yaca_enc_algo_e algo, + yaca_block_cipher_mode_e bcm, + size_t key_bits, + const EVP_CIPHER **cipher); + 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 2debe7d..4365e3c 100644 --- a/src/key.c +++ b/src/key.c @@ -93,7 +93,7 @@ struct yaca_key_evp_s *key_get_evp(const yaca_key_h key) } } -API int yaca_key_get_length(const yaca_key_h key) +API int yaca_key_get_bits(const yaca_key_h 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); diff --git a/src/seal.c b/src/seal.c index cc4b1c9..c39b8be 100644 --- a/src/seal.c +++ b/src/seal.c @@ -30,56 +30,400 @@ #include "internal.h" +enum seal_op_type { + OP_SEAL = 0, + OP_OPEN = 1 +}; + +struct yaca_seal_ctx_s +{ + struct yaca_ctx_s ctx; + + EVP_CIPHER_CTX *cipher_ctx; + enum seal_op_type op_type; /* Operation context was created for */ +}; + +static struct yaca_seal_ctx_s *get_seal_ctx(const yaca_ctx_h ctx) +{ + if (ctx == YACA_CTX_NULL) + return NULL; + + switch (ctx->type) + { + case YACA_CTX_SEAL: + return (struct yaca_seal_ctx_s *)ctx; + default: + return NULL; + } +} + +static void destroy_seal_ctx(const yaca_ctx_h ctx) +{ + struct yaca_seal_ctx_s *nc = get_seal_ctx(ctx); + + if (nc == NULL) + return; + + EVP_CIPHER_CTX_free(nc->cipher_ctx); + nc->cipher_ctx = NULL; +} + +static int get_seal_output_length(const yaca_ctx_h ctx, size_t input_len) +{ + struct yaca_seal_ctx_s *nc = get_seal_ctx(ctx); + int block_size; + + if (nc == NULL) + return YACA_ERROR_INVALID_ARGUMENT; + assert(nc->cipher_ctx); + + block_size = EVP_CIPHER_CTX_block_size(nc->cipher_ctx); + if (block_size <= 0) { + ERROR_DUMP(YACA_ERROR_OPENSSL_FAILURE); + return YACA_ERROR_OPENSSL_FAILURE; + } + + if (input_len > 0) + return block_size + input_len - 1; + return block_size; +} + +static int seal_init(yaca_ctx_h *ctx, + const yaca_key_h pub_key, + yaca_enc_algo_e algo, + yaca_block_cipher_mode_e bcm, + yaca_key_bits_e sym_key_bits, + yaca_key_h *sym_key, + yaca_key_h *iv) +{ + struct yaca_key_evp_s *lpub; + struct yaca_key_simple_s *lkey; + struct yaca_key_simple_s *liv; + struct yaca_seal_ctx_s *nc; + const EVP_CIPHER *cipher; + int pub_key_length; + int iv_length; + int ret; + + if (ctx == NULL || pub_key == YACA_KEY_NULL) + return YACA_ERROR_INVALID_ARGUMENT; + + if (pub_key->type != YACA_KEY_TYPE_RSA_PUB) + return YACA_ERROR_INVALID_ARGUMENT; + lpub = key_get_evp(pub_key); + assert(lpub); + + nc = yaca_zalloc(sizeof(struct yaca_seal_ctx_s)); + if (nc == NULL) + return YACA_ERROR_OUT_OF_MEMORY; + + nc->ctx.type = YACA_CTX_SEAL; + nc->ctx.ctx_destroy = destroy_seal_ctx; + nc->ctx.get_output_length = get_seal_output_length; + nc->op_type = OP_SEAL; + + nc->cipher_ctx = EVP_CIPHER_CTX_new(); + if (nc->cipher_ctx == NULL) { + ret = YACA_ERROR_OPENSSL_FAILURE; + ERROR_DUMP(ret); + goto err_free; + } + + ret = EVP_PKEY_size(lpub->evp); + if (ret <= 0) { + ret = YACA_ERROR_OPENSSL_FAILURE; + ERROR_DUMP(ret); + goto err_ctx; + } + + pub_key_length = ret; + lkey = yaca_zalloc(sizeof(struct yaca_key_simple_s) + pub_key_length); + if (lkey == NULL) { + ret = YACA_ERROR_OUT_OF_MEMORY; + goto err_ctx; + } + + ret = encrypt_get_algorithm(algo, bcm, sym_key_bits, &cipher); + if (ret != 0) + goto err_key; + + ret = EVP_CIPHER_iv_length(cipher); + if (ret < 0) { + ret = YACA_ERROR_OPENSSL_FAILURE; + ERROR_DUMP(ret); + goto err_key; + } + + iv_length = ret; + liv = yaca_zalloc(sizeof(struct yaca_key_simple_s) + iv_length); + if (liv == NULL) { + ret = YACA_ERROR_OUT_OF_MEMORY; + goto err_key; + } + + unsigned char *key_data = (unsigned char*)lkey->d; + int key_data_length; + + ret = EVP_SealInit(nc->cipher_ctx, + cipher, + &key_data, + &key_data_length, + (unsigned char*)liv->d, + &lpub->evp, + 1); + + if (ret != 1) { + ret = YACA_ERROR_OPENSSL_FAILURE; + ERROR_DUMP(ret); + goto err_iv; + } + + lkey->bits = key_data_length * 8; + lkey->key.type = YACA_KEY_TYPE_SYMMETRIC; + *sym_key = (yaca_key_h)lkey; + + liv->bits = iv_length * 8; + liv->key.type = YACA_KEY_TYPE_IV; + *iv = (yaca_key_h)liv; + + *ctx = (yaca_ctx_h)nc; + + return 0; + +err_iv: + yaca_free(liv); +err_key: + yaca_free(lkey); +err_ctx: + EVP_CIPHER_CTX_free(nc->cipher_ctx); +err_free: + yaca_free(nc); + return ret; +} + +static int open_init(yaca_ctx_h *ctx, + const yaca_key_h prv_key, + yaca_enc_algo_e algo, + yaca_block_cipher_mode_e bcm, + yaca_key_bits_e sym_key_bits, + const yaca_key_h sym_key, + const yaca_key_h iv) +{ + const struct yaca_key_evp_s *lprv; + const struct yaca_key_simple_s *lkey; + const struct yaca_key_simple_s *liv; + struct yaca_seal_ctx_s *nc; + const EVP_CIPHER *cipher; + int iv_bits; + int ret; + + if (ctx == NULL || prv_key == YACA_KEY_NULL || sym_key == YACA_KEY_NULL) + return YACA_ERROR_INVALID_ARGUMENT; + + if (prv_key->type != YACA_KEY_TYPE_RSA_PRIV) + return YACA_ERROR_INVALID_ARGUMENT; + lprv = key_get_evp(prv_key); + assert(lprv); + + lkey = key_get_simple(sym_key); + if (lkey == NULL || lkey->key.type != YACA_KEY_TYPE_SYMMETRIC) + return YACA_ERROR_INVALID_ARGUMENT; + + nc = yaca_zalloc(sizeof(struct yaca_seal_ctx_s)); + if (nc == NULL) + return YACA_ERROR_OUT_OF_MEMORY; + + nc->ctx.type = YACA_CTX_SEAL; + nc->ctx.ctx_destroy = destroy_seal_ctx; + nc->ctx.get_output_length = get_seal_output_length; + nc->op_type = OP_OPEN; + + ret = encrypt_get_algorithm(algo, bcm, sym_key_bits, &cipher); + if (ret != 0) + goto err_free; + + ret = EVP_CIPHER_iv_length(cipher); + if (ret < 0) { + ret = YACA_ERROR_OPENSSL_FAILURE; + ERROR_DUMP(ret); + goto err_free; + } + + iv_bits = ret * 8; + if (iv_bits == 0 && iv != NULL) { /* 0 -> cipher doesn't use iv, but it was provided */ + ret = YACA_ERROR_INVALID_ARGUMENT; + goto err_free; + } + + liv = key_get_simple(iv); + /* cipher requires iv, but none was provided, or provided wrong iv */ + if (iv_bits != 0 && (liv == NULL || liv->key.type != YACA_KEY_TYPE_IV)) { + ret = YACA_ERROR_INVALID_ARGUMENT; + goto err_free; + } + + // TODO: handling of algorithms with variable IV length + if (iv_bits != yaca_key_get_bits(iv)) { /* IV length doesn't match cipher */ + ret = YACA_ERROR_INVALID_ARGUMENT; + goto err_free; + } + + nc->cipher_ctx = EVP_CIPHER_CTX_new(); + if (nc->cipher_ctx == NULL) { + ret = YACA_ERROR_OPENSSL_FAILURE; + ERROR_DUMP(ret); + goto err_free; + } + + ret = EVP_OpenInit(nc->cipher_ctx, cipher, + (unsigned char*)lkey->d, + EVP_PKEY_size(lprv->evp), + (unsigned char*)liv->d, + lprv->evp); + if (ret != 1) { + ret = YACA_ERROR_OPENSSL_FAILURE; + ERROR_DUMP(ret); + goto err_ctx; + } + + *ctx = (yaca_ctx_h)nc; + return 0; + +err_ctx: + EVP_CIPHER_CTX_free(nc->cipher_ctx); +err_free: + yaca_free(nc); + return ret; +} + +static int seal_update(yaca_ctx_h ctx, + const unsigned char *input, + size_t input_len, + unsigned char *output, + size_t *output_len, + enum seal_op_type op_type) +{ + struct yaca_seal_ctx_s *c = get_seal_ctx(ctx); + int ret; + + if (c == NULL || input == NULL || input_len == 0 || + output == NULL || output_len == NULL || op_type != c->op_type) + return YACA_ERROR_INVALID_ARGUMENT; + + switch (op_type) { + case OP_SEAL: + ret = EVP_SealUpdate(c->cipher_ctx, output, (int*)output_len, input, input_len); + break; + case OP_OPEN: + ret = EVP_OpenUpdate(c->cipher_ctx, output, (int*)output_len, input, input_len); + break; + default: + return YACA_ERROR_INVALID_ARGUMENT; + } + + if (ret != 1) { + ret = YACA_ERROR_OPENSSL_FAILURE; + ERROR_DUMP(ret); + return ret; + } + + return 0; +} + +static int seal_final(yaca_ctx_h ctx, + unsigned char *output, + size_t *output_len, + enum seal_op_type op_type) +{ + struct yaca_seal_ctx_s *c = get_seal_ctx(ctx); + int ret; + + if (c == NULL || output == NULL || output_len == NULL || op_type != c->op_type) + return YACA_ERROR_INVALID_ARGUMENT; + + switch (op_type) { + case OP_SEAL: + ret = EVP_SealFinal(c->cipher_ctx, output, (int*)output_len); + break; + case OP_OPEN: + ret = EVP_OpenFinal(c->cipher_ctx, output, (int*)output_len); + break; + default: + return YACA_ERROR_INVALID_ARGUMENT; + } + + if (ret != 1) { + ret = YACA_ERROR_OPENSSL_FAILURE; + ERROR_DUMP(ret); + return ret; + } + + return 0; +} + API int yaca_seal_init(yaca_ctx_h *ctx, - const yaca_key_h pub_key, - yaca_enc_algo_e algo, - yaca_block_cipher_mode_e bcm, - yaca_key_bits_e sym_key_bits, - yaca_key_h *sym_key, - yaca_key_h *iv) + const yaca_key_h pub_key, + yaca_enc_algo_e algo, + yaca_block_cipher_mode_e bcm, + yaca_key_bits_e sym_key_bits, + yaca_key_h *sym_key, + yaca_key_h *iv) { - return YACA_ERROR_NOT_IMPLEMENTED; + return seal_init(ctx, pub_key, algo, bcm, sym_key_bits, sym_key, iv); } API int yaca_seal_update(yaca_ctx_h ctx, - const char *plain, - size_t plain_len, - char *cipher, - size_t *cipher_len) + const char *plain, + size_t plain_len, + char *cipher, + size_t *cipher_len) { - return YACA_ERROR_NOT_IMPLEMENTED; + return seal_update(ctx, + (const unsigned char*)plain, + plain_len, + (unsigned char*)cipher, + cipher_len, + OP_SEAL); } API int yaca_seal_final(yaca_ctx_h ctx, - char *cipher, - size_t *cipher_len) + char *cipher, + size_t *cipher_len) { - return YACA_ERROR_NOT_IMPLEMENTED; + return seal_final(ctx, + (unsigned char*)cipher, + cipher_len, + OP_SEAL); } API int yaca_open_init(yaca_ctx_h *ctx, - const yaca_key_h prv_key, - yaca_enc_algo_e algo, - yaca_block_cipher_mode_e bcm, - yaca_key_bits_e sym_key_bits, - const yaca_key_h sym_key, - const yaca_key_h iv) + const yaca_key_h prv_key, + yaca_enc_algo_e algo, + yaca_block_cipher_mode_e bcm, + yaca_key_bits_e sym_key_bits, + const yaca_key_h sym_key, + const yaca_key_h iv) { - return YACA_ERROR_NOT_IMPLEMENTED; + return open_init(ctx, prv_key, algo, bcm, sym_key_bits, sym_key, iv); } API int yaca_open_update(yaca_ctx_h ctx, - const char *cipher, - size_t cipher_len, - char *plain, - size_t *plain_len) + const char *cipher, + size_t cipher_len, + char *plain, + size_t *plain_len) { - return YACA_ERROR_NOT_IMPLEMENTED; + return seal_update(ctx, + (const unsigned char*)cipher, + cipher_len, + (unsigned char*)plain, + plain_len, + OP_OPEN); } API int yaca_open_final(yaca_ctx_h ctx, - char *plain, - size_t *plain_len) + char *plain, + size_t *plain_len) { - return YACA_ERROR_NOT_IMPLEMENTED; + return seal_final(ctx, (unsigned char*)plain, plain_len, OP_OPEN); } -- 2.7.4 From 67a9f817aec8be46f57c1c69333fc8f7d25a7814 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Thu, 21 Apr 2016 13:06:31 +0200 Subject: [PATCH 03/16] Review and simplify Seal/Open example. Change-Id: I3d41c8de8edf79237027162f654af65952a5d9d3 --- examples/seal.c | 95 +++++++++++++++++++++++---------------------------------- 1 file changed, 39 insertions(+), 56 deletions(-) diff --git a/examples/seal.c b/examples/seal.c index c913b48..a631c91 100644 --- a/examples/seal.c +++ b/examples/seal.c @@ -32,7 +32,9 @@ void encrypt_seal(void) { - int ret; + 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; yaca_ctx_h ctx = YACA_CTX_NULL; yaca_key_h key_pub = YACA_KEY_NULL; yaca_key_h key_priv = YACA_KEY_NULL; @@ -44,98 +46,78 @@ void encrypt_seal(void) size_t enc_size; size_t dec_size; - printf("Plain data (16 of %zu bytes): %.16s\n", (size_t)4096, lorem1024); + size_t block_len; + size_t output_len; + size_t out_size; + size_t rem; - /// Generate key pair - ret = yaca_key_gen_pair(&key_priv, &key_pub, - YACA_KEY_TYPE_PAIR_RSA, - YACA_KEY_2048BIT); - if (ret) return; + printf("Plain data (16 of %zu bytes): %.16s\n", LOREM4096_SIZE, lorem4096); - /// Encrypt a.k.a. seal - { - size_t out_size; - size_t rem; + /* Generate key pair */ + if (yaca_key_gen_pair(&key_priv, &key_pub, YACA_KEY_TYPE_PAIR_RSA, YACA_KEY_4096BIT) != 0) + return; - ret = yaca_seal_init(&ctx, key_pub, - YACA_ENC_AES, YACA_BCM_CBC, YACA_KEY_192BIT, - &aes_key, &iv); - if (ret < 0) + /* Encrypt a.k.a. seal */ + { + if (yaca_seal_init(&ctx, key_pub, algo, bcm, key_bits, &aes_key, &iv) != 0) goto ex_pk; - ret = yaca_seal_update(ctx, lorem4096, 4096, NULL, &enc_size); - if (ret < 0) + if ((block_len = yaca_get_block_length(ctx)) <= 0) goto ex_ak; - ret = yaca_get_block_length(ctx); - if (ret < 0) + if ((output_len = yaca_get_output_length(ctx, LOREM4096_SIZE)) <= 0) goto ex_ak; - enc_size = enc_size + ret; - enc = yaca_malloc(enc_size); - if (enc == NULL) + /* Calculate max output: size of update + final chunks */ + enc_size = output_len + block_len; + if ((enc = yaca_malloc(enc_size)) == NULL) goto ex_ak; - // Seal and finalize + /* Seal and finalize */ out_size = enc_size; - ret = yaca_seal_update(ctx, lorem4096, 4096, enc, &out_size); - if (ret < 0) + if (yaca_seal_update(ctx, lorem4096, LOREM4096_SIZE, enc, &out_size) != 0) goto ex_of; rem = enc_size - out_size; - ret = yaca_seal_final(ctx, enc + out_size, &rem); - if (ret < 0) + if (yaca_seal_final(ctx, enc + out_size, &rem) != 0) goto ex_of; enc_size = rem + out_size; dump_hex(enc, 16, "Encrypted data (16 of %zu bytes): ", enc_size); - yaca_ctx_free(ctx); // TODO: perhaps it should not return value + yaca_ctx_free(ctx); + ctx = YACA_CTX_NULL; } - /// Decrypt a.k.a. open + /* 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, YACA_KEY_192BIT, - aes_key, iv); - if (ret < 0) { - yaca_free(enc); - goto ex_ak; - } + if (yaca_open_init(&ctx, key_priv, algo, bcm, key_bits, aes_key, iv) != 0) + goto ex_of; - ret = yaca_open_update(ctx, enc, enc_size, NULL, &dec_size); - if (ret < 0) + if ((block_len = yaca_get_block_length(ctx)) <= 0) goto ex_of; - ret = yaca_get_block_length(ctx); - if (ret < 0) + if ((output_len = yaca_get_output_length(ctx, LOREM4096_SIZE)) <= 0) goto ex_of; - dec_size = dec_size + ret; - dec = yaca_malloc(dec_size); - if (dec == NULL) + /* Calculate max output: size of update + final chunks */ + dec_size = output_len + block_len; + if ((dec = yaca_malloc(dec_size)) == NULL) goto ex_of; - // Seal and finalize - out_size = enc_size; - ret = yaca_open_update(ctx, enc, enc_size, dec, &out_size); - if (ret < 0) + /* Open and finalize */ + out_size = dec_size; + if (yaca_open_update(ctx, enc, enc_size, dec, &out_size) != 0) goto ex_in; rem = dec_size - out_size; - ret = yaca_open_final(ctx, dec + out_size, &rem); - if (ret < 0) + if (yaca_open_final(ctx, dec + out_size, &rem) != 0) goto ex_in; dec_size = rem + out_size; - printf("Decrypted data (16 of %zu bytes): %.16s\n", (size_t)dec_size, dec); - - yaca_ctx_free(ctx); // TODO: perhaps it should not return value + printf("Decrypted data (16 of %zu bytes): %.16s\n", dec_size, dec); } ex_in: @@ -143,6 +125,7 @@ ex_in: ex_of: yaca_free(enc); ex_ak: + yaca_ctx_free(ctx); yaca_key_free(aes_key); yaca_key_free(iv); ex_pk: @@ -160,6 +143,6 @@ int main() encrypt_seal(); - yaca_exit(); // TODO: what about handing of return value from exit?? + yaca_exit(); return ret; } -- 2.7.4 From 76c758b272e5837520af1837c1fa49f68ff5f5fe Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Thu, 28 Apr 2016 13:07:47 +0200 Subject: [PATCH 04/16] Cleanup API documentation. Change-Id: I4e4e1ce027d9672adb1bf92eebfc8e8696f90cb5 --- api/yaca/crypto.h | 39 ++++++++----- api/yaca/digest.h | 16 +++-- api/yaca/encrypt.h | 86 +++++++++++++++------------ api/yaca/error.h | 27 +++++---- api/yaca/key.h | 94 ++++++++++++++++-------------- api/yaca/seal.h | 86 +++++++++++++++------------ api/yaca/sign.h | 56 ++++++++++-------- api/yaca/simple.h | 74 +++++++++++++----------- api/yaca/types.h | 167 ++++++++++++++++++++++++++++++++++++----------------- doc/doxygen.cfg | 4 +- 10 files changed, 386 insertions(+), 263 deletions(-) diff --git a/api/yaca/crypto.h b/api/yaca/crypto.h index b3d16db..52c7a32 100644 --- a/api/yaca/crypto.h +++ b/api/yaca/crypto.h @@ -32,7 +32,7 @@ extern "C" { #endif /** - * @defgroup Non-Crypto Non crypto related functions. + * @defgroup Non-Crypto Yet Another Crypto API - non crypto related functions. * * TODO: extended description and examples. * @@ -47,13 +47,15 @@ extern "C" { /** * @brief yaca_init Initializes the library. Must be called before any other crypto function. * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. + * @see yaca_exit() */ int yaca_init(void); /** * @brief yaca_exit Closes the library. Must be called before exiting the application. * + * @see yaca_init() */ void yaca_exit(void); @@ -63,6 +65,7 @@ void yaca_exit(void); * @param[in] size Size of the allocation (bytes). * * @return NULL on failure, pointer to allocated memory otherwise. + * @see yaca_zalloc(), yaca_realloc(), yaca_free() */ // TODO: this should be a macro to CRYPTO_* void *yaca_malloc(size_t size); @@ -73,6 +76,7 @@ void *yaca_malloc(size_t size); * @param[in] size Size of the allocation (bytes). * * @return NULL on failure, pointer to allocated and zeroed memory otherwise. + * @see yaca_malloc(), yaca_realloc(), yaca_free() */ // TODO: this should be a macro to CRYPTO_* void *yaca_zalloc(size_t size); @@ -84,15 +88,17 @@ void *yaca_zalloc(size_t size); * @param[in] size Size of the new allocation (bytes). * * @return NULL on failure, pointer to allocated memory otherwise. + * @see yaca_malloc(), yaca_zalloc(), yaca_free() */ // TODO: this should be a macro to CRYPTO_* void *yaca_realloc(void *addr, size_t size); /** - * @brief yaca_free Frees the memory allocated by @see yaca_malloc - * or one of the cryptographics operations. + * @brief yaca_free Frees the memory allocated by yaca_malloc(), yaca_zalloc(), + * yaca_realloc() or one of the cryptographic operations. * * @param[in] ptr Pointer to the memory to be freed. + * @see yaca_malloc(), yaca_zalloc(), yaca_realloc() * */ // TODO: this should be a macro to CRYPTO_* @@ -104,7 +110,7 @@ void yaca_free(void *ptr); * @param[in,out] data Pointer to the memory to be randomized. * @param[in] data_len Length of the memory to be randomized. * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. */ int yaca_rand_bytes(char *data, size_t data_len); @@ -117,10 +123,13 @@ int yaca_rand_bytes(char *data, size_t data_len); * @param[in] value Parameter value. * @param[in] value_len Length of the parameter value. * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. + * @see #yaca_ex_param_e, yaca_ctx_get_param() */ -int yaca_ctx_set_param(yaca_ctx_h ctx, yaca_ex_param_e param, - const void *value, size_t value_len); +int yaca_ctx_set_param(yaca_ctx_h ctx, + yaca_ex_param_e param, + const void *value, + size_t value_len); /** * @brief yaca_ctx_get_param Returns the extended context parameters. @@ -128,13 +137,16 @@ int yaca_ctx_set_param(yaca_ctx_h ctx, yaca_ex_param_e param, * * @param[in] ctx Previously initialized crypto context. * @param[in] param Parameter to be read. - * @param[out] value Copy of the parameter value (must be freed with @see yaca_free). + * @param[out] value Copy of the parameter value (must be freed with yaca_free()). * @param[out] value_len Length of the parameter value will be returned here. * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. + * @see #yaca_ex_param_e, yaca_ctx_set_param() */ -int yaca_ctx_get_param(const yaca_ctx_h ctx, yaca_ex_param_e param, - void **value, size_t *value_len); +int yaca_ctx_get_param(const yaca_ctx_h ctx, + yaca_ex_param_e param, + void **value, + size_t *value_len); /** * @brief yaca_ctx_free Destroys the crypto context. Must be called @@ -142,6 +154,7 @@ int yaca_ctx_get_param(const yaca_ctx_h ctx, yaca_ex_param_e param, * Passing YACA_CTX_NULL is allowed. * * @param[in,out] ctx Crypto context. + * @see #yaca_ctx_h * */ void yaca_ctx_free(yaca_ctx_h ctx); @@ -153,7 +166,7 @@ void yaca_ctx_free(yaca_ctx_h ctx); * @param[in] ctx Previously initialized crypto context. * @param[in] input_len Length of the input data to be processed. * - * @return negative on error (@see error.h) or length of output. + * @return negative on error or length of output. */ // TODO: this function should probably return the value by param of // size_t type and leave the return int value only to report errors diff --git a/api/yaca/digest.h b/api/yaca/digest.h index 1e8edf3..dc49b92 100644 --- a/api/yaca/digest.h +++ b/api/yaca/digest.h @@ -42,21 +42,23 @@ extern "C" { /** * @brief yaca_digest_init Initializes a digest context. * - * @param[out] ctx Newly created context (must be freed with @see yaca_ctx_free). + * @param[out] ctx Newly created context (must be freed with yaca_ctx_free()). * @param[in] algo Digest algorithm that will be used. * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. + * @see #yaca_digest_algo_e, yaca_digest_update(), yaca_digest_final() */ int yaca_digest_init(yaca_ctx_h *ctx, yaca_digest_algo_e algo); /** * @brief yaca_digest_update Feeds the data into the message digest algorithm. * - * @param[in,out] ctx Context created by @see yaca_digest_init. + * @param[in,out] ctx Context created by yaca_digest_init(). * @param[in] data Data from which the digest is to be calculated. * @param[in] data_len Length of the data. * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. + * @see yaca_digest_init(), yaca_digest_final() */ int yaca_digest_update(yaca_ctx_h ctx, const char *data, size_t data_len); @@ -64,10 +66,12 @@ int yaca_digest_update(yaca_ctx_h ctx, const char *data, size_t data_len); * @brief yaca_digest_final Calculates the final digest. * * @param[in,out] ctx A valid digest context. - * @param[out] digest Buffer for the message digest (must be allocated by client, @see yaca_get_digest_length). + * @param[out] digest Buffer for the message digest (must be allocated by client, + * see yaca_get_digest_length()). * @param[out] digest_len Length of the digest, actual number of bytes written will be returned here. * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. + * @see yaca_digest_init(), yaca_digest_update() */ int yaca_digest_final(yaca_ctx_h ctx, char *digest, size_t *digest_len); diff --git a/api/yaca/encrypt.h b/api/yaca/encrypt.h index 8c52fc9..b62541d 100644 --- a/api/yaca/encrypt.h +++ b/api/yaca/encrypt.h @@ -44,109 +44,119 @@ extern "C" { /** * @brief yaca_encrypt_init Initializes an encryption context. * - * @param[out] ctx Newly created context (must be freed with @see yaca_ctx_free). + * @param[out] ctx Newly created context (must be freed with yaca_ctx_free()). * @param[in] algo Encryption algorithm that will be used. * @param[in] bcm Chaining mode that will be used. * @param[in] sym_key Symmetric key that will be used. * @param[in] iv Initialization vector that will be used. * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. + * @see #yaca_enc_algo_e, #yaca_block_cipher_mode_e, yaca_encrypt_update(), yaca_encrypt_final() */ int yaca_encrypt_init(yaca_ctx_h *ctx, - yaca_enc_algo_e algo, - yaca_block_cipher_mode_e bcm, - const yaca_key_h sym_key, - const yaca_key_h iv); + yaca_enc_algo_e algo, + yaca_block_cipher_mode_e bcm, + const yaca_key_h sym_key, + const yaca_key_h iv); /** * @brief yaca_encrypt_update Encrypts chunk of the data. * - * @param[in,out] ctx Context created by @see yaca_encrypt_init. + * @param[in,out] ctx Context created by yaca_encrypt_init(). * @param[in] plain Plain text to be encrypted. * @param[in] plain_len Length of the plain text. - * @param[out] cipher Buffer for the encrypted data (must be allocated by client, @see yaca_get_output_length). + * @param[out] cipher Buffer for the encrypted data (must be allocated by client, see + * yaca_get_output_length()). * @param[out] cipher_len Length of the encrypted data, actual number of bytes written will be returned here. * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. + * @see yaca_encrypt_init(), yaca_encrypt_final() */ int yaca_encrypt_update(yaca_ctx_h ctx, - const char *plain, - size_t plain_len, - char *cipher, - size_t *cipher_len); + const char *plain, + size_t plain_len, + char *cipher, + size_t *cipher_len); /** * @brief yaca_encrypt_final Encrypts the final chunk of the data. * * @param[in,out] ctx A valid encrypt context. - * @param[out] cipher Final piece of the encrypted data (must be allocated by client, @see yaca_get_block_length). + * @param[out] cipher Final piece of the encrypted data (must be allocated by client, see + * yaca_get_block_length()). * @param[out] cipher_len Length of the final piece, actual number of bytes written will be returned here. * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. + * @see yaca_encrypt_init(), yaca_encrypt_update() */ int yaca_encrypt_final(yaca_ctx_h ctx, - char *cipher, - size_t *cipher_len); + char *cipher, + size_t *cipher_len); /** * @brief yaca_decrypt_init Initializes an decryption context. * - * @param[out] ctx Newly created context (must be freed with @see yaca_ctx_free). + * @param[out] ctx Newly created context (must be freed with yaca_ctx_free()). * @param[in] algo Encryption 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 key that was used to encrypt the data. * @param[in] iv Initialization vector that was used to encrypt the data. * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. + * @see #yaca_enc_algo_e, #yaca_block_cipher_mode_e, yaca_decrypt_update(), yaca_decrypt_final() */ int yaca_decrypt_init(yaca_ctx_h *ctx, - yaca_enc_algo_e algo, - yaca_block_cipher_mode_e bcm, - const yaca_key_h sym_key, - const yaca_key_h iv); + yaca_enc_algo_e algo, + yaca_block_cipher_mode_e bcm, + const yaca_key_h sym_key, + const yaca_key_h iv); /** * @brief yaca_decrypt_update Decrypts chunk of the data. * - * @param[in,out] ctx Context created by @see yaca_decrypt_init. + * @param[in,out] ctx Context created by yaca_decrypt_init(). * @param[in] cipher Cipher text to be decrypted. * @param[in] cipher_len Length of the cipher text. - * @param[out] plain Buffer for the decrypted data (must be allocated by client, @see yaca_get_output_length). + * @param[out] plain Buffer for the decrypted data (must be allocated by client, see + * yaca_get_output_length()). * @param[out] plain_len Length of the decrypted data, actual number of bytes written will be returned here. * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. + * @see yaca_decrypt_init(), yaca_decrypt_final() */ int yaca_decrypt_update(yaca_ctx_h ctx, - const char *cipher, - size_t cipher_len, - char *plain, - size_t *plain_len); + const char *cipher, + size_t cipher_len, + char *plain, + size_t *plain_len); /** * @brief yaca_decrypt_final Decrypts the final chunk of the data. * * @param[in,out] ctx A valid decrypt context. - * @param[out] plain Final piece of the decrypted data (must be allocated by client, @see yaca_get_block_length). + * @param[out] plain Final piece of the decrypted data (must be allocated by client, see + * yaca_get_block_length()). * @param[out] plain_len Length of the final piece, actual number of bytes written will be returned here. * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. + * @see yaca_decrypt_init(), yaca_decrypt_update() */ int yaca_decrypt_final(yaca_ctx_h ctx, - char *plain, - size_t *plain_len); + char *plain, + size_t *plain_len); /** * @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). + * @param[in] key_bits Key length in bits. * - * @return negative on error (@see error.h) or the IV length in bits. + * @return negative on error or the IV length in bits. */ int yaca_get_iv_bits(yaca_enc_algo_e algo, - yaca_block_cipher_mode_e bcm, - size_t key_bits); + yaca_block_cipher_mode_e bcm, + size_t key_bits); /**@}*/ diff --git a/api/yaca/error.h b/api/yaca/error.h index 5012c34..d82c3fc 100644 --- a/api/yaca/error.h +++ b/api/yaca/error.h @@ -24,21 +24,27 @@ #ifndef ERROR_H #define ERROR_H -/* - TODO: Error enums should be placed here - */ #ifdef __cplusplus extern "C" { #endif +/** + * @defgroup Error Yet another Crypto API - error enums and debug functions. + * + * @{ + */ + +/** + * @brief Error enums + */ enum __yaca_error_code { - YACA_ERROR_INVALID_ARGUMENT = -1, - YACA_ERROR_NOT_IMPLEMENTED = -2, - YACA_ERROR_OPENSSL_FAILURE = -3, - YACA_ERROR_NOT_SUPPORTED = -4, - YACA_ERROR_TOO_BIG_ARGUMENT = -5, - YACA_ERROR_OUT_OF_MEMORY = -6, - YACA_ERROR_SIGNATURE_INVALID = -7 + YACA_ERROR_INVALID_ARGUMENT = -1, + YACA_ERROR_NOT_IMPLEMENTED = -2, + YACA_ERROR_OPENSSL_FAILURE = -3, + YACA_ERROR_NOT_SUPPORTED = -4, + YACA_ERROR_TOO_BIG_ARGUMENT = -5, + YACA_ERROR_OUT_OF_MEMORY = -6, + YACA_ERROR_SIGNATURE_INVALID = -7 }; // TODO disable debug function in release? @@ -58,6 +64,7 @@ typedef void (*yaca_debug_func)(const char*); */ void yaca_error_set_debug_func(yaca_debug_func fn); +/**@}*/ #ifdef __cplusplus } /* extern */ diff --git a/api/yaca/key.h b/api/yaca/key.h index 114b02c..c9c924c 100644 --- a/api/yaca/key.h +++ b/api/yaca/key.h @@ -32,7 +32,7 @@ extern "C" { #endif /** - * @defgroup Key Key and IV handling functions + * @defgroup Key Advanced API for the key and IV handling. * * TODO: extended description and examples. * @@ -48,77 +48,81 @@ extern "C" { * * @param[in] key Key which length we return. * - * @return negative on error (@see error.h) or key length (in bits). + * @return negative on error or key length (in bits). */ int yaca_key_get_bits(const yaca_key_h key); /** * @brief yaca_key_import Imports a key from the arbitrary format. * - * @param[out] key Returned key (must be freed with @see yaca_key_free). + * @param[out] key Returned key (must be freed with yaca_key_free()). * @param[in] key_fmt Format of the key. * @param[in] key_type Type of the key. * @param[in] data Blob containing the key. * @param[in] data_len Size of the blob. * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. + * @see #yaca_key_fmt_e, #yaca_key_type_e, yaca_key_export(), yaca_key_free() */ int yaca_key_import(yaca_key_h *key, - yaca_key_fmt_e key_fmt, - yaca_key_type_e key_type, - const char *data, - size_t data_len); + yaca_key_fmt_e key_fmt, + yaca_key_type_e key_type, + const char *data, + size_t data_len); /** * @brief yaca_key_export Exports a key to arbitrary format. Export may fail if key is HW-based. * * @param[in] key Key to be exported. * @param[in] key_fmt Format of the key. - * @param[out] data Data, allocated by the library, containing exported key (must be freed with @see yaca_free). + * @param[out] data Data, allocated by the library, containing exported key + * (must be freed with yaca_free()). * @param[out] data_len Size of the output data. * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. + * @see #yaca_key_fmt_e, yaca_key_import(), yaca_key_free() */ int yaca_key_export(const yaca_key_h key, - yaca_key_fmt_e key_fmt, - char **data, - size_t *data_len); - -// TODO: still a matter of ordering, should the key in key_gen functions be first or last? + yaca_key_fmt_e key_fmt, + char **data, + size_t *data_len); /** * @brief yaca_key_gen Generates a secure symmetric key (or an initialization vector). * - * @param[out] sym_key Newly generated key (must be freed with @see yaca_key_free). + * @param[out] sym_key Newly generated key (must be freed with yaca_key_free()). * @param[in] key_type Type 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). + * @return 0 on success, negative on error. + * @see #yaca_key_type_e, #yaca_key_bits_e, yaca_key_gen_pair(), yaca_key_free() */ int yaca_key_gen(yaca_key_h *sym_key, - yaca_key_type_e key_type, - size_t key_bits); + yaca_key_type_e key_type, + size_t key_bits); /** * @brief yaca_key_gen_pair Generates a new key pair. * - * @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[out] prv_key Newly generated private key (must be freed with yaca_key_free()). + * @param[out] pub_key Newly generated public key (must be freed with yaca_key_free()). * @param[in] key_type Type of the key to be generated (must be YACA_KEY_TYPE_PAIR*). * @param[in] key_bits Length of the key (in bits) to be generated. * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. + * @see #yaca_key_type_e, #yaca_key_bits_e, yaca_key_gen(), yaca_key_free() */ int yaca_key_gen_pair(yaca_key_h *prv_key, - yaca_key_h *pub_key, - yaca_key_type_e key_type, - size_t key_bits); + yaca_key_h *pub_key, + yaca_key_type_e key_type, + size_t key_bits); /** * @brief yaca_key_free Frees the key created by the library. * Passing YACA_KEY_NULL is allowed. * * @param key Key to be freed. + * @see yaca_key_import(), yaca_key_export(), yaca_key_gen(), yaca_key_gen_pair() * */ void yaca_key_free(yaca_key_h key); @@ -126,7 +130,7 @@ void yaca_key_free(yaca_key_h key); /**@}*/ /** - * @defgroup Key-Derivation Key derivation functions + * @defgroup Key-Derivation Advanced API for the key derivation. * * TODO: rethink separate group. * TODO: extended description and examples. @@ -139,13 +143,14 @@ void yaca_key_free(yaca_key_h key); * * @param[in] prv_key Our private key. * @param[in] pub_key Peer public key. - * @param[out] sym_key Shared secret, that can be used as a symmetric key (must be freed with @see yaca_key_free). + * @param[out] sym_key Shared secret, that can be used as a symmetric key + * (must be freed with yaca_key_free()). * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. */ int yaca_key_derive_dh(const yaca_key_h prv_key, - const yaca_key_h pub_key, - yaca_key_h *sym_key); + const yaca_key_h pub_key, + yaca_key_h *sym_key); /** * @brief yaca_key_derive_kea Derives a key using KEA key exchange protocol. @@ -156,15 +161,16 @@ int yaca_key_derive_dh(const yaca_key_h prv_key, * DH public component sent to peer to verify our identity. * @param[in] pub_key_auth Peers' public key used for signature verification * of pub_key from peer (peer authentication). - * @param[out] sym_key Shared secret, that can be used as a symmetric key (must be freed with @see yaca_key_free). + * @param[out] sym_key Shared secret, that can be used as a symmetric key + * (must be freed with yaca_key_free()). * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. */ int yaca_key_derive_kea(const yaca_key_h prv_key, - const yaca_key_h pub_key, - const yaca_key_h prv_key_auth, - const yaca_key_h pub_key_auth, - yaca_key_h *sym_key); + const yaca_key_h pub_key, + const yaca_key_h prv_key_auth, + const yaca_key_h pub_key_auth, + yaca_key_h *sym_key); /** * @brief yaca_key_derive_pbkdf2 Derives a key from user password (PKCS #5 a.k.a. pbkdf2 algorithm). @@ -175,17 +181,17 @@ int yaca_key_derive_kea(const yaca_key_h prv_key, * @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_bits Length of a key (in bits) to be generated. - * @param[out] key Newly generated key (must be freed with @see yaca_key_free). + * @param[out] key Newly generated key (must be freed with yaca_key_free()). * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. */ int yaca_key_derive_pbkdf2(const char *password, - const char *salt, - size_t salt_len, - int iter, - yaca_digest_algo_e algo, - size_t key_bits, - yaca_key_h *key); + const char *salt, + size_t salt_len, + int iter, + yaca_digest_algo_e algo, + size_t key_bits, + yaca_key_h *key); // TODO: specify //int yaca_key_wrap(yaca_key_h key, ??); diff --git a/api/yaca/seal.h b/api/yaca/seal.h index 3467291..a6897be 100644 --- a/api/yaca/seal.h +++ b/api/yaca/seal.h @@ -46,7 +46,7 @@ extern "C" { /** * @brief yaca_seal_init Initializes an asymmetric encryption context. * - * @param[out] ctx Newly created context (must be freed with @see yaca_ctx_free). + * @param[out] ctx Newly created context (must be freed with yaca_ctx_free()). * @param[in] pub_key Public key of the peer that will receive the encrypted data. * @param[in] algo Symmetric algorithm that will be used. * @param[in] bcm Block chaining mode for the symmetric algorithm. @@ -54,50 +54,55 @@ extern "C" { * @param[out] sym_key Generated symmetric key that will be used. It is encrypted with peer's public key. * @param[out] iv Generated initialization vector that will be used. * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. + * @see #yaca_enc_algo_e, #yaca_block_cipher_mode_e, yaca_seal_update(), yaca_seal_final() */ int yaca_seal_init(yaca_ctx_h *ctx, - const yaca_key_h pub_key, - yaca_enc_algo_e algo, - yaca_block_cipher_mode_e bcm, - yaca_key_bits_e sym_key_bits, - yaca_key_h *sym_key, - yaca_key_h *iv); + const yaca_key_h pub_key, + yaca_enc_algo_e algo, + yaca_block_cipher_mode_e bcm, + yaca_key_bits_e sym_key_bits, + yaca_key_h *sym_key, + yaca_key_h *iv); /** * @brief yaca_seal_update Encrypts piece of the data. * - * @param[in,out] ctx Context created by @see yaca_seal_init. + * @param[in,out] ctx Context created by yaca_seal_init(). * @param[in] plain Plain text to be encrypted. * @param[in] plain_len Length of the plain text. - * @param[out] cipher Buffer for the encrypted data (must be allocated by client, @see yaca_get_output_length). + * @param[out] cipher Buffer for the encrypted data (must be allocated by client, see + * yaca_get_output_length()). * @param[out] cipher_len Length of the encrypted data, actual number of bytes written will be returned here. * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. + * @see yaca_seal_init(), yaca_seal_final() */ int yaca_seal_update(yaca_ctx_h ctx, - const char *plain, - size_t plain_len, - char *cipher, - size_t *cipher_len); + const char *plain, + size_t plain_len, + char *cipher, + size_t *cipher_len); /** * @brief yaca_seal_final Encrypts the final piece of the data. * * @param[in,out] ctx A valid seal context. - * @param[out] cipher Final piece of the encrypted data (must be allocated by client, @see yaca_get_block_length). + * @param[out] cipher Final piece of the encrypted data (must be allocated by client, see + * yaca_get_block_length()). * @param[out] cipher_len Length of the final piece, actual number of bytes written will be returned here. * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. + * @see yaca_seal_init(), yaca_seal_update() */ int yaca_seal_final(yaca_ctx_h ctx, - char *cipher, - size_t *cipher_len); + char *cipher, + size_t *cipher_len); /** * @brief yaca_open_init Initializes an asymmetric decryption context. * - * @param[out] ctx Newly created context. Must be freed by @see yaca_ctx_free. + * @param[out] ctx Newly created context. Must be freed by yaca_ctx_free(). * @param[in] prv_key Private key, part of the pair that was used for the encryption. * @param[in] algo Symmetric algorithm that was used for the encryption. * @param[in] bcm Block chaining mode for the symmetric algorithm. @@ -105,45 +110,50 @@ int yaca_seal_final(yaca_ctx_h ctx, * @param[in] sym_key Symmetric key, encrypted with the public key, that was used to encrypt the data. * @param[in] iv Initialization vector that was used for the encryption. * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. + * @see #yaca_enc_algo_e, #yaca_block_cipher_mode_e, yaca_open_update(), yaca_open_final() */ int yaca_open_init(yaca_ctx_h *ctx, - const yaca_key_h prv_key, - yaca_enc_algo_e algo, - yaca_block_cipher_mode_e bcm, - yaca_key_bits_e sym_key_bits, - const yaca_key_h sym_key, - const yaca_key_h iv); + const yaca_key_h prv_key, + yaca_enc_algo_e algo, + yaca_block_cipher_mode_e bcm, + yaca_key_bits_e sym_key_bits, + const yaca_key_h sym_key, + const yaca_key_h iv); /** * @brief yaca_open_update Decrypts piece of the data. * - * @param[in,out] ctx Context created by @see yaca_open_init. + * @param[in,out] ctx Context created by yaca_open_init(). * @param[in] cipher Cipher text to be decrypted. * @param[in] cipher_len Length of the cipher text. - * @param[out] plain Buffer for the decrypted data (must be allocated by client, @see yaca_get_output_length). + * @param[out] plain Buffer for the decrypted data (must be allocated by client, see + * yaca_get_output_length()). * @param[out] plain_len Length of the decrypted data, actual number of bytes written will be returned here. * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. + * @see yaca_open_init(), yaca_open_final() */ int yaca_open_update(yaca_ctx_h ctx, - const char *cipher, - size_t cipher_len, - char *plain, - size_t *plain_len); + const char *cipher, + size_t cipher_len, + char *plain, + size_t *plain_len); /** * @brief yaca_open_final Decrypts last chunk of sealed message. * * @param[in,out] ctx A valid open context. - * @param[out] plain Final piece of the decrypted data (must be allocated by client, @see yaca_get_block_length). + * @param[out] plain Final piece of the decrypted data (must be allocated by client, see + * yaca_get_block_length()). * @param[out] plain_len Length of the final piece, actual number of bytes written will be returned here. * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. + * @see yaca_open_init(), yaca_open_update() */ int yaca_open_final(yaca_ctx_h ctx, - char *plain, - size_t *plain_len); + char *plain, + size_t *plain_len); /**@}*/ diff --git a/api/yaca/sign.h b/api/yaca/sign.h index 217d15d..91c47d1 100644 --- a/api/yaca/sign.h +++ b/api/yaca/sign.h @@ -43,81 +43,87 @@ extern "C" { /** * @brief yaca_sign_init Initializes a signature context. * - * @param[out] ctx Newly created context (must be freed with @see yaca_ctx_free). + * @param[out] ctx Newly created context (must be freed with yaca_ctx_free()). * @param[in] algo Digest algorithm that will be used. * @param[in] key Private or symmetric key that will be used (algorithm is deduced based on key type). * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. + * @see #yaca_digest_algo_e, yaca_sign_update(), yaca_sign_final() */ int yaca_sign_init(yaca_ctx_h *ctx, - yaca_digest_algo_e algo, - const yaca_key_h key); + yaca_digest_algo_e algo, + const yaca_key_h key); /** * @brief yaca_sign_update Feeds the data into the digital signature algorithm. * - * @param[in,out] ctx Context created by @see yaca_sign_init. + * @param[in,out] ctx Context created by yaca_sign_init(). * @param[in] data Data to be signed. * @param[in] data_len Length of the data. * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. + * @see yaca_sign_init(), yaca_sign_final() */ int yaca_sign_update(yaca_ctx_h ctx, - const char *data, - size_t data_len); + const char *data, + size_t data_len); /** * @brief yaca_sign_final Calculates the final signature. * * @param[in,out] ctx A valid sign context. - * @param[out] mac Buffer for the MAC or the signature (must be allocated by client, @see yaca_get_sign_length). + * @param[out] mac Buffer for the MAC or the signature (must be allocated by client, see + * yaca_get_sign_length()). * @param[out] mac_len Length of the MAC or the signature, actual number of bytes written will be returned here. * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. + * @see yaca_sign_init(), yaca_sign_update() */ int yaca_sign_final(yaca_ctx_h ctx, - char *mac, - size_t *mac_len); + char *mac, + size_t *mac_len); /** * @brief yaca_verify_init Initializes a signature verification context. * - * @param[out] ctx Newly created context (must be freed with @see yaca_ctx_free). + * @param[out] ctx Newly created context (must be freed with yaca_ctx_free()). * @param[in] algo Digest algorithm that will be used. * @param[in] key Private or symmetric key that will be used (algorithm is deduced based on key type). * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. + * @see #yaca_digest_algo_e, yaca_verify_update(), yaca_verify_final() */ int yaca_verify_init(yaca_ctx_h *ctx, - yaca_digest_algo_e algo, - const yaca_key_h key); + yaca_digest_algo_e algo, + const yaca_key_h key); /** * @brief yaca_verify_update Feeds the data into the digital signature verification algorithm. * - * @param[in,out] ctx Context created by @see yaca_verify_init. + * @param[in,out] ctx Context created by yaca_verify_init(). * @param[in] data Data to be verified. * @param[in] data_len Length of the data. * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. + * @see yaca_verify_init(), yaca_verify_final() */ int yaca_verify_update(yaca_ctx_h ctx, - const char *data, - size_t data_len); + const char *data, + size_t data_len); /** * @brief yaca_verify_final Performs the verification. * * @param[in,out] ctx A valid verify context. - * @param[in] mac Input MAC or signature (returned by @see yaca_sign_final). + * @param[in] mac Input MAC or signature (returned by yaca_sign_final()). * @param[in] mac_len Size of the MAC or the signature. * - * @return 0 on success, negative on error (@see error.h). - * TODO: YACA_ERROR_SIGNATURE_INVALID when verification fails. + * @return 0 on success, negative on error. + * @see yaca_verify_init(), yaca_verify_update() */ int yaca_verify_final(yaca_ctx_h ctx, - const char *mac, - size_t mac_len); + const char *mac, + size_t mac_len); /**@}*/ diff --git a/api/yaca/simple.h b/api/yaca/simple.h index 8a7dc25..3075aac 100644 --- a/api/yaca/simple.h +++ b/api/yaca/simple.h @@ -50,65 +50,71 @@ extern "C" { /** * @brief yaca_digest_calc Calculate a digest of a buffer. * - * @param[in] algo Digest algorithm (select @see YACA_DIGEST_SHA256 if unsure). + * @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. - * @param[out] digest Message digest, will be allocated by the library (should be freed with @see yaca_free). + * @param[out] digest Message digest, will be allocated by the library + * (should be freed with yaca_free()). * @param[out] digest_len Length of message digest (depends on algorithm). * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. + * @see #yaca_digest_algo_e */ int yaca_digest_calc(yaca_digest_algo_e algo, - const char *data, - size_t data_len, - char **digest, - size_t *digest_len); + const char *data, + size_t data_len, + char **digest, + size_t *digest_len); /** * @brief yaca_encrypt Encrypt data using a symmetric cipher. * - * @param[in] algo Encryption algorithm (select @see YACA_ENC_AES if unsure). - * @param[in] bcm Chaining mode (select @see YACA_BCM_CBC if unsure). - * @param[in] sym_key Symmetric encryption key (@see key.h for key generation functions). + * @param[in] algo Encryption algorithm (select #YACA_ENC_AES if unsure). + * @param[in] bcm Chaining mode (select #YACA_BCM_CBC if unsure). + * @param[in] sym_key Symmetric encryption key (see key.h for key generation functions). * @param[in] iv Initialization vector. * @param[in] plain Plain text to be encrypted. * @param[in] plain_len Length of the plain text. - * @param[out] cipher Encrypted data, will be allocated by the library (should be freed with @see yaca_free). + * @param[out] cipher Encrypted data, will be allocated by the library + * (should be freed with yaca_free()). * @param[out] cipher_len Length of the encrypted data (may be larger than decrypted). * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. + * @see #yaca_enc_algo_e, #yaca_block_cipher_mode_e, yaca_decrypt() */ int yaca_encrypt(yaca_enc_algo_e algo, - yaca_block_cipher_mode_e bcm, - const yaca_key_h sym_key, - const yaca_key_h iv, - const char *plain, - size_t plain_len, - char **cipher, - size_t *cipher_len); + yaca_block_cipher_mode_e bcm, + const yaca_key_h sym_key, + const yaca_key_h iv, + const char *plain, + size_t plain_len, + char **cipher, + size_t *cipher_len); /** * @brief yaca_decrypt Decrypta data using a symmetric cipher. * - * @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. - * @param[in] iv Initialization vector that was used to encrypt the data. - * @param[in] cipher Cipher text to be decrypted. - * @param[in] cipher_len Length of cipher text. - * @param[out] plain Decrypted data, will be allocated by the library (should be freed with @see yaca_free). + * @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. + * @param[in] iv Initialization vector that was used to encrypt the data. + * @param[in] cipher Cipher text to be decrypted. + * @param[in] cipher_len Length of cipher text. + * @param[out] plain Decrypted data, will be allocated by the library + * (should be freed with yaca_free()). * @param[out] plain_len Length of the decrypted data. * - * @return 0 on success, negative on error (@see error.h). + * @return 0 on success, negative on error. + * @see #yaca_enc_algo_e, #yaca_block_cipher_mode_e, yaca_encrypt() */ int yaca_decrypt(yaca_enc_algo_e algo, - yaca_block_cipher_mode_e bcm, - const yaca_key_h sym_key, - const yaca_key_h iv, - const char *cipher, - size_t cipher_len, - char **plain, - size_t * plain_len); + yaca_block_cipher_mode_e bcm, + const yaca_key_h sym_key, + const yaca_key_h iv, + const char *cipher, + size_t cipher_len, + char **plain, + size_t * plain_len); // TODO: sign/verify diff --git a/api/yaca/types.h b/api/yaca/types.h index 19428df..80750bf 100644 --- a/api/yaca/types.h +++ b/api/yaca/types.h @@ -29,7 +29,7 @@ extern "C" { #endif /** - * @defgroup Crypto-Types Enumerations for CryptoAPI + * @defgroup Crypto-Types Yet Another Crypto API - types. * * TODO: extended description. * @@ -128,63 +128,124 @@ typedef enum { * @brief Symmetric encryption algorithms */ typedef enum { - YACA_ENC_AES = 0, /**< AES encryption. - - see #yaca_block_cipher_mode_e for details on additional parameters (mandatory) - Supported key lengths: @c 128, @c 192 and @c 256 */ - - YACA_ENC_UNSAFE_DES, /**< DES encryption. - - see #yaca_block_cipher_mode_e for details on additional parameters (mandatory) - Supported key lengths: @c 56 */ - - YACA_ENC_UNSAFE_3DES_2TDEA, /**< 3DES 2-key encryption. - - see #yaca_block_cipher_mode_e for details on additional parameters (mandatory) - Use double DES keys to perform corresponding 2-key 3DES encryption. Supported key lengths: @c 112 */ - - YACA_ENC_3DES_3TDEA, /**< 3DES 3-key encryption. - - see #yaca_block_cipher_mode_e for details on additional parameters (mandatory) - Use triple DES keys to perform corresponding 3-key 3DES encryption. Supported key lengths: @c 168 */ - - YACA_ENC_UNSAFE_RC2, /**< RC2 encryption. - - see #yaca_block_cipher_mode_e for details on additional parameters (mandatory) - The key length is extracted from the key buffer. Supported key lengths: 8-1024 bits in steps of 8 bits. */ - - YACA_ENC_UNSAFE_RC4, /**< RC4 encryption. - The key length is extracted from the key buffer. Supported key lengths: 40–2048 bits in steps of 8 bits */ - - YACA_ENC_CAST5, /**< CAST5 encryption. - - see #yaca_block_cipher_mode_e for details on additional parameters (mandatory) - The key length is extracted from the key buffer. Supported key lengths: 40-128 bits in steps of 8 bits */ - - YACA_ENC_UNSAFE_SKIPJACK /**< SKIPJACK algorithm - - see #yaca_block_cipher_mode_e for details on additional parameters (mandatory) - Supported key length: 80 bits */ + /** + * AES encryption. + * - see #yaca_block_cipher_mode_e for details on additional parameters (mandatory). + * - Supported key lengths: @c 128, @c 192 and @c 256. + */ + YACA_ENC_AES = 0, + + /** + * DES encryption. + * - see #yaca_block_cipher_mode_e for details on additional parameters (mandatory). + * - Supported key lengths: @c 56. + */ + YACA_ENC_UNSAFE_DES, + + /** + * 3DES 2-key encryption. + * - see #yaca_block_cipher_mode_e for details on additional parameters (mandatory). + * - Use double DES keys to perform corresponding 2-key 3DES encryption. + * - Supported key lengths: @c 112. + */ + YACA_ENC_UNSAFE_3DES_2TDEA, + + /** + * 3DES 3-key encryption. + * - see #yaca_block_cipher_mode_e for details on additional parameters (mandatory). + * - Use triple DES keys to perform corresponding 3-key 3DES encryption. + * - Supported key lengths: @c 168. + */ + YACA_ENC_3DES_3TDEA, + + /** + * RC2 encryption. + * - The key length is extracted from the key buffer. + * - Supported key lengths: 8-1024 bits in steps of 8 bits. + */ + YACA_ENC_UNSAFE_RC2, + + /** + * RC4 encryption. + * - The key length is extracted from the key buffer. + * - Supported key lengths: 40–2048 bits in steps of 8 bits. + */ + YACA_ENC_UNSAFE_RC4, + + /** + * CAST5 encryption. + * - see #yaca_block_cipher_mode_e for details on additional parameters (mandatory). + * - The key length is extracted from the key buffer. + * - Supported key lengths: 40-128 bits in steps of 8 bits. + */ + YACA_ENC_CAST5, + + /** + * SKIPJACK algorithm. + * - Supported key length: 80 bits. + */ + YACA_ENC_UNSAFE_SKIPJACK } yaca_enc_algo_e; /** * @brief Chaining modes for block ciphers */ typedef enum { - YACA_BCM_ECB, /**< ECB block cipher mode. Encrypts 64 bit at a time. No IV is used. */ - - YACA_BCM_CTR, /**< CTR block cipher mode. 16-byte initialization vector is mandatory. - Supported parameters: - - YACA_PARAM_CTR_CNT = length of counter block in bits - (optional, only 128b is supported at the moment) */ - - YACA_BCM_CBC, /**< CBC block cipher mode. 16-byte initialization vector is mandatory. */ - - YACA_BCM_GCM, /**< GCM block cipher mode. IV is needed. - Supported parameters: - - YACA_PARAM_TAG = GCM tag - - YACA_PARAM_AAD = additional authentication data(optional) */ - - YACA_BCM_CFB, /**< CFB block cipher mode. 16-byte initialization vector is mandatory. */ - - YACA_BCM_OFB, /**< OFB block cipher mode. 16-byte initialization vector is mandatory. */ - - YACA_BCM_OCB, /**< Offest Codebook Mode (AES) */ - - YACA_BCM_CCM /**< CBC-MAC Mode (AES) */ + /** + * ECB block cipher mode. + * Encrypts 64 bit at a time. No IV is used. + */ + YACA_BCM_ECB, + + /** + * CTR block cipher mode. + * 16-byte initialization vector is mandatory. + * Supported parameters: + * - #YACA_PARAM_CTR_CNT = length of counter block in bits + * (optional, only 128b is supported at the moment) + */ + YACA_BCM_CTR, + + /** + * CBC block cipher mode. + * 16-byte initialization vector is mandatory. + */ + YACA_BCM_CBC, + + /** + * GCM block cipher mode, IV is needed. + * Supported parameters: + * - #YACA_PARAM_GCM_TAG = GCM tag + * - #YACA_PARAM_GCM_TAG_LEN = GCM tag length + * - #YACA_PARAM_GCM_AAD = additional authentication data(optional) + */ + YACA_BCM_GCM, + + /** + * CFB block cipher mode. + * 16-byte initialization vector is mandatory. + */ + YACA_BCM_CFB, + + /** + * OFB block cipher mode. + * 16-byte initialization vector is mandatory. + */ + YACA_BCM_OFB, + + /** + * Offest Codebook Mode (AES) + */ + YACA_BCM_OCB, + + /** + * CBC-MAC Mode (AES). + * Supported parameters: + * - #YACA_PARAM_CCM_TAG = CCM tag + * - #YACA_PARAM_CCM_TAG_LEN = CCM tag length + * - #YACA_PARAM_CCM_AAD = additional authentication data(optional) + */ + YACA_BCM_CCM } yaca_block_cipher_mode_e; @@ -207,7 +268,7 @@ typedef enum { } yaca_ex_param_e; /** - * @brief Paddings supported by CryptoAPI + * @brief Paddings supported by Yet Another Crypto API */ typedef enum { YACA_PADDING_NONE = 0, /**< total number of data MUST multiple of block size, Default */ diff --git a/doc/doxygen.cfg b/doc/doxygen.cfg index b6a7957..87e9f10 100644 --- a/doc/doxygen.cfg +++ b/doc/doxygen.cfg @@ -551,7 +551,7 @@ INLINE_INFO = YES # name. If set to NO, the members will appear in declaration order. # The default value is: YES. -SORT_MEMBER_DOCS = YES +SORT_MEMBER_DOCS = NO # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief # descriptions of file, namespace and class members alphabetically by member @@ -578,7 +578,7 @@ SORT_MEMBERS_CTORS_1ST = NO # appear in their defined order. # The default value is: NO. -SORT_GROUP_NAMES = NO +SORT_GROUP_NAMES = YES # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by # fully-qualified names, including namespaces. If set to NO, the class list will -- 2.7.4 From 82526fc1f310cc359f2bcfbc8a95b137a23171bd Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Thu, 28 Apr 2016 14:01:30 +0200 Subject: [PATCH 05/16] Replace YACA_ERROR_OPENSSL_FAILURE with YACA_ERROR_INTERNAL Change-Id: Ibb6ffca3dc778479556ba7412b46b3f9c542c424 --- api/yaca/error.h | 2 +- src/crypto.c | 2 +- src/digest.c | 10 +++++----- src/encrypt.c | 16 ++++++++-------- src/key.c | 12 ++++++------ src/seal.c | 22 +++++++++++----------- src/sign.c | 22 +++++++++++----------- 7 files changed, 43 insertions(+), 43 deletions(-) diff --git a/api/yaca/error.h b/api/yaca/error.h index d82c3fc..eaca621 100644 --- a/api/yaca/error.h +++ b/api/yaca/error.h @@ -40,7 +40,7 @@ extern "C" { enum __yaca_error_code { YACA_ERROR_INVALID_ARGUMENT = -1, YACA_ERROR_NOT_IMPLEMENTED = -2, - YACA_ERROR_OPENSSL_FAILURE = -3, + YACA_ERROR_INTERNAL = -3, YACA_ERROR_NOT_SUPPORTED = -4, YACA_ERROR_TOO_BIG_ARGUMENT = -5, YACA_ERROR_OUT_OF_MEMORY = -6, diff --git a/src/crypto.c b/src/crypto.c index bfcb358..734dba5 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -90,7 +90,7 @@ API int yaca_rand_bytes(char *data, size_t data_len) if (ret == -1) ret = YACA_ERROR_NOT_SUPPORTED; else - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); return ret; diff --git a/src/digest.c b/src/digest.c index e23f7b5..b9f4ce4 100644 --- a/src/digest.c +++ b/src/digest.c @@ -108,7 +108,7 @@ int digest_get_algorithm(yaca_digest_algo_e algo, const EVP_MD **md) } if (ret == 0 && *md == NULL) { - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); } @@ -138,14 +138,14 @@ API int yaca_digest_init(yaca_ctx_h *ctx, yaca_digest_algo_e algo) nc->mdctx = EVP_MD_CTX_create(); if (nc->mdctx == NULL) { - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); goto free; } ret = EVP_DigestInit(nc->mdctx, md); if (ret != 1) { - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); goto ctx; } @@ -171,7 +171,7 @@ API int yaca_digest_update(yaca_ctx_h ctx, const char *data, size_t data_len) ret = EVP_DigestUpdate(c->mdctx, data, data_len); if (ret != 1) { - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); return ret; } @@ -193,7 +193,7 @@ API int yaca_digest_final(yaca_ctx_h ctx, char *digest, size_t *digest_len) ret = EVP_DigestFinal_ex(c->mdctx, (unsigned char*)digest, &len); if (ret != 1) { - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); return ret; } diff --git a/src/encrypt.c b/src/encrypt.c index 3fee076..40aa2ee 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -78,8 +78,8 @@ static int get_encrypt_output_length(const yaca_ctx_h ctx, size_t input_len) block_size = EVP_CIPHER_CTX_block_size(nc->cipher_ctx); if (block_size == 0) { - ERROR_DUMP(YACA_ERROR_OPENSSL_FAILURE); - return YACA_ERROR_OPENSSL_FAILURE; + ERROR_DUMP(YACA_ERROR_INTERNAL); + return YACA_ERROR_INTERNAL; } if (input_len > 0) @@ -158,7 +158,7 @@ int encrypt_get_algorithm(yaca_enc_algo_e algo, lcipher = EVP_get_cipherbyname(cipher_name); if (lcipher == NULL) { - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); return ret; } @@ -210,7 +210,7 @@ static int encrypt_init(yaca_ctx_h *ctx, ret = EVP_CIPHER_iv_length(cipher); if (ret < 0) { - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); goto err_free; } @@ -235,7 +235,7 @@ static int encrypt_init(yaca_ctx_h *ctx, nc->cipher_ctx = EVP_CIPHER_CTX_new(); if (nc->cipher_ctx == NULL) { - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); goto err_free; } @@ -257,7 +257,7 @@ static int encrypt_init(yaca_ctx_h *ctx, } if (ret != 1) { - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); goto err_ctx; } @@ -303,7 +303,7 @@ static int encrypt_update(yaca_ctx_h ctx, } if (ret != 1) { - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); return ret; } @@ -339,7 +339,7 @@ static int encrypt_final(yaca_ctx_h ctx, } if (ret != 1) { - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); return ret; } diff --git a/src/key.c b/src/key.c index 4365e3c..477fb18 100644 --- a/src/key.c +++ b/src/key.c @@ -111,7 +111,7 @@ API int yaca_key_get_bits(const yaca_key_h key) // TODO: handle ECC keys when they're implemented ret = EVP_PKEY_bits(evp_key->evp); if (ret <= 0) { - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); return ret; } @@ -297,7 +297,7 @@ API int yaca_key_gen_pair(yaca_key_h *prv_key, ret = BN_set_word(bne, RSA_F4); if (ret != 1) { - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); goto free_bne; } @@ -311,7 +311,7 @@ API int yaca_key_gen_pair(yaca_key_h *prv_key, ret = RSA_generate_key_ex(rsa, key_bits, bne, NULL); if (ret != 1) { - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); goto free_rsa; } @@ -332,14 +332,14 @@ API int yaca_key_gen_pair(yaca_key_h *prv_key, ret = EVP_PKEY_assign_RSA(nk_prv->evp, RSAPrivateKey_dup(rsa)); if (ret != 1) { - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); goto free_evp_pub; } ret = EVP_PKEY_assign_RSA(nk_pub->evp, RSAPublicKey_dup(rsa)); if (ret != 1) { - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); goto free_evp_pub; } @@ -439,7 +439,7 @@ API int yaca_key_derive_pbkdf2(const char *password, salt_len, iter, md, key_byte_len, (unsigned char*)nk->d); if (ret != 1) { - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); goto err; } diff --git a/src/seal.c b/src/seal.c index c39b8be..a5fb2ae 100644 --- a/src/seal.c +++ b/src/seal.c @@ -79,8 +79,8 @@ static int get_seal_output_length(const yaca_ctx_h ctx, size_t input_len) block_size = EVP_CIPHER_CTX_block_size(nc->cipher_ctx); if (block_size <= 0) { - ERROR_DUMP(YACA_ERROR_OPENSSL_FAILURE); - return YACA_ERROR_OPENSSL_FAILURE; + ERROR_DUMP(YACA_ERROR_INTERNAL); + return YACA_ERROR_INTERNAL; } if (input_len > 0) @@ -124,14 +124,14 @@ static int seal_init(yaca_ctx_h *ctx, nc->cipher_ctx = EVP_CIPHER_CTX_new(); if (nc->cipher_ctx == NULL) { - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); goto err_free; } ret = EVP_PKEY_size(lpub->evp); if (ret <= 0) { - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); goto err_ctx; } @@ -149,7 +149,7 @@ static int seal_init(yaca_ctx_h *ctx, ret = EVP_CIPHER_iv_length(cipher); if (ret < 0) { - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); goto err_key; } @@ -173,7 +173,7 @@ static int seal_init(yaca_ctx_h *ctx, 1); if (ret != 1) { - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); goto err_iv; } @@ -244,7 +244,7 @@ static int open_init(yaca_ctx_h *ctx, ret = EVP_CIPHER_iv_length(cipher); if (ret < 0) { - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); goto err_free; } @@ -270,7 +270,7 @@ static int open_init(yaca_ctx_h *ctx, nc->cipher_ctx = EVP_CIPHER_CTX_new(); if (nc->cipher_ctx == NULL) { - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); goto err_free; } @@ -281,7 +281,7 @@ static int open_init(yaca_ctx_h *ctx, (unsigned char*)liv->d, lprv->evp); if (ret != 1) { - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); goto err_ctx; } @@ -322,7 +322,7 @@ static int seal_update(yaca_ctx_h ctx, } if (ret != 1) { - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); return ret; } @@ -353,7 +353,7 @@ static int seal_final(yaca_ctx_h ctx, } if (ret != 1) { - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); return ret; } diff --git a/src/sign.c b/src/sign.c index a77b403..0c789bc 100644 --- a/src/sign.c +++ b/src/sign.c @@ -104,8 +104,8 @@ static int create_sign_pkey(const yaca_key_h key, EVP_PKEY **pkey) (unsigned char *)simple_key->d, simple_key->bits / 8); if (*pkey == NULL) { - ERROR_DUMP(YACA_ERROR_OPENSSL_FAILURE); - return YACA_ERROR_OPENSSL_FAILURE; + ERROR_DUMP(YACA_ERROR_INTERNAL); + return YACA_ERROR_INTERNAL; } return 0; @@ -174,7 +174,7 @@ API int yaca_sign_init(yaca_ctx_h *ctx, nc->mdctx = EVP_MD_CTX_create(); if (nc->mdctx == NULL) { - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); goto free_ctx; } @@ -186,7 +186,7 @@ API int yaca_sign_init(yaca_ctx_h *ctx, goto ctx; } if (ret != 1) { - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); goto ctx; } @@ -225,7 +225,7 @@ API int yaca_sign_update(yaca_ctx_h ctx, if (ret == -2) ret = YACA_ERROR_NOT_SUPPORTED; else - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); return ret; @@ -249,7 +249,7 @@ API int yaca_sign_final(yaca_ctx_h ctx, if (ret == -2) ret = YACA_ERROR_NOT_SUPPORTED; else - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); return ret; @@ -305,7 +305,7 @@ API int yaca_verify_init(yaca_ctx_h *ctx, nc->mdctx = EVP_MD_CTX_create(); if (nc->mdctx == NULL) { - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); goto free_ctx; } @@ -329,7 +329,7 @@ API int yaca_verify_init(yaca_ctx_h *ctx, goto ctx; } if (ret != 1) { - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); goto ctx; } @@ -378,7 +378,7 @@ API int yaca_verify_update(yaca_ctx_h ctx, if (ret == -2) ret = YACA_ERROR_NOT_SUPPORTED; else - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); return ret; @@ -411,7 +411,7 @@ API int yaca_verify_final(yaca_ctx_h ctx, if (ret == -2) ret = YACA_ERROR_NOT_SUPPORTED; else - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); return ret; @@ -427,7 +427,7 @@ API int yaca_verify_final(yaca_ctx_h ctx, else if (ret == -2) ret = YACA_ERROR_NOT_SUPPORTED; else - ret = YACA_ERROR_OPENSSL_FAILURE; + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); return ret; -- 2.7.4 From e78e0eda6122a683bffdebe9070fc1d17a27356e Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Mon, 25 Apr 2016 15:31:22 +0200 Subject: [PATCH 06/16] Switch to smart-tabs in key.c and key.h Change-Id: I8d6186819fe1edb3cea5a58124e06e4b1fbbbac9 --- src/key.c | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/key.c b/src/key.c index 477fb18..6f47834 100644 --- a/src/key.c +++ b/src/key.c @@ -123,10 +123,10 @@ API int yaca_key_get_bits(const yaca_key_h key) } API int yaca_key_import(yaca_key_h *key, - yaca_key_fmt_e key_fmt, - yaca_key_type_e key_type, - const char *data, - size_t data_len) + yaca_key_fmt_e key_fmt, + yaca_key_type_e key_type, + const char *data, + size_t data_len) { if (key == NULL || data == NULL || data_len == 0) return YACA_ERROR_INVALID_ARGUMENT; @@ -164,9 +164,9 @@ API int yaca_key_import(yaca_key_h *key, } API int yaca_key_export(const yaca_key_h key, - yaca_key_fmt_e key_fmt, - char **data, - size_t *data_len) + yaca_key_fmt_e key_fmt, + char **data, + size_t *data_len) { size_t byte_len; struct yaca_key_simple_s *simple_key = key_get_simple(key); @@ -199,8 +199,8 @@ 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_bits) + yaca_key_type_e key_type, + size_t key_bits) { int ret; struct yaca_key_simple_s *nk = NULL; @@ -259,9 +259,9 @@ 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_bits) + yaca_key_h *pub_key, + yaca_key_type_e key_type, + size_t key_bits) { int ret; struct yaca_key_evp_s *nk_prv = NULL; @@ -386,28 +386,28 @@ API void yaca_key_free(yaca_key_h key) } API int yaca_key_derive_dh(const yaca_key_h prv_key, - const yaca_key_h pub_key, - yaca_key_h *sym_key) + const yaca_key_h pub_key, + yaca_key_h *sym_key) { return YACA_ERROR_NOT_IMPLEMENTED; } API int yaca_key_derive_kea(const yaca_key_h prv_key, - const yaca_key_h pub_key, - const yaca_key_h prv_key_auth, - const yaca_key_h pub_key_auth, - yaca_key_h *sym_key) + const yaca_key_h pub_key, + const yaca_key_h prv_key_auth, + const yaca_key_h pub_key_auth, + yaca_key_h *sym_key) { return YACA_ERROR_NOT_IMPLEMENTED; } API int yaca_key_derive_pbkdf2(const char *password, - const char *salt, - size_t salt_len, - int iter, - yaca_digest_algo_e algo, - size_t key_bits, - yaca_key_h *key) + const char *salt, + size_t salt_len, + int iter, + yaca_digest_algo_e algo, + size_t key_bits, + yaca_key_h *key) { const EVP_MD *md; struct yaca_key_simple_s *nk; @@ -436,8 +436,8 @@ API int yaca_key_derive_pbkdf2(const char *password, 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_byte_len, - (unsigned char*)nk->d); + salt_len, iter, md, key_byte_len, + (unsigned char*)nk->d); if (ret != 1) { ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); -- 2.7.4 From e14076c63ee6c0954c7e0036e9ff1f41f2ce827b Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Wed, 20 Apr 2016 15:19:50 +0200 Subject: [PATCH 07/16] Rename key_fmt to key_file_fmt type and introduce a real key_fmt enum. key_file_fmt is a format of the file (PEM, DER, RAW, BASE64). Newly added key_fmt is a format of a key within file format (PKCS#X, etc). E.g. we can have PKCS#1 encoded as PEM or DER and PKCS#8 encoded again as PEM or DER. Those two format types are independent of each other. Change-Id: I38b9106c619a5b45c09be48d95f9278f43b79dd4 --- api/yaca/key.h | 24 ++++++++++++------------ api/yaca/types.h | 16 ++++++++++++---- examples/encrypt_aes_gcm.c | 2 +- examples/key_exchange.c | 4 ++-- examples/test.c | 2 +- src/key.c | 8 ++++---- todo.txt | 2 ++ 7 files changed, 34 insertions(+), 24 deletions(-) diff --git a/api/yaca/key.h b/api/yaca/key.h index c9c924c..dd1dbe8 100644 --- a/api/yaca/key.h +++ b/api/yaca/key.h @@ -55,17 +55,17 @@ int yaca_key_get_bits(const yaca_key_h key); /** * @brief yaca_key_import Imports a key from the arbitrary format. * - * @param[out] key Returned key (must be freed with yaca_key_free()). - * @param[in] key_fmt Format of the key. - * @param[in] key_type Type of the key. - * @param[in] data Blob containing the key. - * @param[in] data_len Size of the blob. + * @param[out] key Returned key (must be freed with yaca_key_free()). + * @param[in] key_file_fmt Format of the key file. + * @param[in] key_type Type of the key. + * @param[in] data Blob containing the key. + * @param[in] data_len Size of the blob. * * @return 0 on success, negative on error. * @see #yaca_key_fmt_e, #yaca_key_type_e, yaca_key_export(), yaca_key_free() */ int yaca_key_import(yaca_key_h *key, - yaca_key_fmt_e key_fmt, + yaca_key_file_fmt_e key_file_fmt, yaca_key_type_e key_type, const char *data, size_t data_len); @@ -73,17 +73,17 @@ int yaca_key_import(yaca_key_h *key, /** * @brief yaca_key_export Exports a key to arbitrary format. Export may fail if key is HW-based. * - * @param[in] key Key to be exported. - * @param[in] key_fmt Format of the key. - * @param[out] data Data, allocated by the library, containing exported key - * (must be freed with yaca_free()). - * @param[out] data_len Size of the output data. + * @param[in] key Key to be exported. + * @param[in] key_file_fmt Format of the key. + * @param[out] data Data, allocated by the library, containing exported key + * (must be freed with yaca_free()). + * @param[out] data_len Size of the output data. * * @return 0 on success, negative on error. * @see #yaca_key_fmt_e, yaca_key_import(), yaca_key_free() */ int yaca_key_export(const yaca_key_h key, - yaca_key_fmt_e key_fmt, + yaca_key_file_fmt_e key_file_fmt, char **data, size_t *data_len); diff --git a/api/yaca/types.h b/api/yaca/types.h index 80750bf..5478a46 100644 --- a/api/yaca/types.h +++ b/api/yaca/types.h @@ -50,13 +50,21 @@ typedef struct yaca_key_s *yaca_key_h; * @brief Key formats */ typedef enum { - YACA_KEY_FORMAT_RAW, /**< key is in clear format */ - YACA_KEY_FORMAT_BASE64, /**< key is encoded in ASCII-base64 */ - YACA_KEY_FORMAT_PEM, /**< key is in PEM file format */ - YACA_KEY_FORMAT_DER /**< key is in DER file format */ + YACA_KEY_FORMAT_DEFAULT, /**< key is either PKCS#1 for RSA or SSLeay for DSA, also use this option for symmetric */ + YACA_KEY_FORMAT_PKCS8 /**< key is in PKCS#8, can only be used for asymmetric private keys */ } yaca_key_fmt_e; /** + * @brief Key file formats + */ +typedef enum { + YACA_KEY_FILE_FORMAT_RAW, /**< key file is in raw binary format, used for symmetric keys */ + YACA_KEY_FILE_FORMAT_BASE64, /**< key file is encoded in ASCII-base64, used for symmetric keys */ + YACA_KEY_FILE_FORMAT_PEM, /**< key file is in PEM file format, used for asymmetric keys */ + YACA_KEY_FILE_FORMAT_DER /**< key file is in DER file format, used for asymmetric keys */ +} yaca_key_file_fmt_e; + +/** * @brief Key types, IV is considered as key */ typedef enum { diff --git a/examples/encrypt_aes_gcm.c b/examples/encrypt_aes_gcm.c index 9b2c6f8..17c51ff 100644 --- a/examples/encrypt_aes_gcm.c +++ b/examples/encrypt_aes_gcm.c @@ -71,7 +71,7 @@ void encrypt_decrypt_aes_gcm(void) goto clean; // generate and export aad? - ret = yaca_key_export(aad_key, YACA_KEY_FORMAT_RAW, &aad, &aad_len); + ret = yaca_key_export(aad_key, YACA_KEY_FILE_FORMAT_RAW, &aad, &aad_len); if (ret < 0) goto clean; diff --git a/examples/key_exchange.c b/examples/key_exchange.c index 2b0b61c..edbcd5d 100644 --- a/examples/key_exchange.c +++ b/examples/key_exchange.c @@ -68,7 +68,7 @@ void key_exchange_dh(void) goto clean; ret = yaca_key_import(&peer_key, - YACA_KEY_FORMAT_RAW, YACA_KEY_TYPE_DH_PUB, + YACA_KEY_FILE_FORMAT_RAW, YACA_KEY_TYPE_DH_PUB, buffer, size); if (ret < 0) goto clean; @@ -124,7 +124,7 @@ void key_exchange_ecdh(void) if (1 != fread(buffer, size, 1, fp)) goto clean; - ret = yaca_key_import(&peer_key, YACA_KEY_FORMAT_RAW, YACA_KEY_TYPE_ECDH_PUB, buffer, size); + ret = yaca_key_import(&peer_key, YACA_KEY_FILE_FORMAT_RAW, YACA_KEY_TYPE_ECDH_PUB, buffer, size); if (ret < 0) goto clean; diff --git a/examples/test.c b/examples/test.c index 22f9632..a26148a 100644 --- a/examples/test.c +++ b/examples/test.c @@ -45,7 +45,7 @@ int main(int argc, char* argv[]) printf("done (%d)\n", ret); printf("Exporting key using CryptoAPI.. "); - ret = yaca_key_export(key, YACA_KEY_FORMAT_RAW, &k, &kl); + ret = yaca_key_export(key, YACA_KEY_FILE_FORMAT_RAW, &k, &kl); if (ret < 0) return ret; printf("done (%d)\n", ret); diff --git a/src/key.c b/src/key.c index 6f47834..eacaccd 100644 --- a/src/key.c +++ b/src/key.c @@ -123,7 +123,7 @@ API int yaca_key_get_bits(const yaca_key_h key) } API int yaca_key_import(yaca_key_h *key, - yaca_key_fmt_e key_fmt, + yaca_key_file_fmt_e key_file_fmt, yaca_key_type_e key_type, const char *data, size_t data_len) @@ -131,7 +131,7 @@ API int yaca_key_import(yaca_key_h *key, if (key == NULL || data == NULL || data_len == 0) return YACA_ERROR_INVALID_ARGUMENT; - if (key_fmt != YACA_KEY_FORMAT_RAW) + if (key_file_fmt != YACA_KEY_FILE_FORMAT_RAW) return YACA_ERROR_NOT_IMPLEMENTED; if (key_type == YACA_KEY_TYPE_SYMMETRIC) { @@ -164,7 +164,7 @@ API int yaca_key_import(yaca_key_h *key, } API int yaca_key_export(const yaca_key_h key, - yaca_key_fmt_e key_fmt, + yaca_key_file_fmt_e key_file_fmt, char **data, size_t *data_len) { @@ -175,7 +175,7 @@ API int yaca_key_export(const yaca_key_h key, if (data == NULL || data_len == NULL) return YACA_ERROR_INVALID_ARGUMENT; - if (key_fmt != YACA_KEY_FORMAT_RAW) + if (key_file_fmt != YACA_KEY_FILE_FORMAT_RAW) return YACA_ERROR_NOT_IMPLEMENTED; if (simple_key != NULL) { diff --git a/todo.txt b/todo.txt index 4f24242..b2e5846 100644 --- a/todo.txt +++ b/todo.txt @@ -1,3 +1,5 @@ Global: - Rethink and possibly add verification of output buffer lengths. In other words check whether the user won't cause a buffer overflow. +- Importing/exporting encrypted (passphrased) RSA keys +- What about importing RSA priv and generating PUB from it? -- 2.7.4 From aaaec9752659528bde03a642ad1d43b9c2ae3945 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Thu, 5 May 2016 12:39:23 +0200 Subject: [PATCH 08/16] Add info about yaca tests. Remove unnecessary test dir. Change-Id: Icb519091c09c426993c50f5fac8ef6d9c1c8c874 --- CMakeLists.txt | 2 -- readme.txt | 6 ++++++ test/.keep | 0 3 files changed, 6 insertions(+), 2 deletions(-) delete mode 100644 test/.keep diff --git a/CMakeLists.txt b/CMakeLists.txt index 78db916..aa4f6ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,7 +76,6 @@ ENDIF() SET(API_FOLDER ${PROJECT_SOURCE_DIR}/api) SET(EXAMPLES_FOLDER ${PROJECT_SOURCE_DIR}/examples) SET(SRC_FOLDER ${PROJECT_SOURCE_DIR}/src) -SET(TEST_FOLDER ${PROJECT_SOURCE_DIR}/test) IF(NOT DEFINED LIB_INSTALL_DIR) SET(LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}") @@ -99,5 +98,4 @@ IF(NOT DEFINED EXAMPLES_DIR) ENDIF(NOT DEFINED EXAMPLES_DIR) ADD_SUBDIRECTORY(${SRC_FOLDER}) -#ADD_SUBDIRECTORY(${TEST_FOLDER}) ADD_SUBDIRECTORY(${EXAMPLES_FOLDER}) diff --git a/readme.txt b/readme.txt index c970a3b..b0fe7f2 100644 --- a/readme.txt +++ b/readme.txt @@ -38,3 +38,9 @@ API: Examples: - It is possible to compile-check examples with "make" command + +Tests: + All tests are developed at security-tests repository from tizen.org, branch yaca. + git clone ssh://[USER_ID]@review.tizen.org:29418/platform/core/test/security-tests -b yaca + Build all tests with command: cmake -DBUILD_ALL_TESTS=OFF -DBUILD_YACA=ON; make + Run all tests with command: yaca-test diff --git a/test/.keep b/test/.keep deleted file mode 100644 index e69de29..0000000 -- 2.7.4 From 04e0b98b70502efc859928d0704627bb7f59e768 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Wed, 20 Apr 2016 16:35:44 +0200 Subject: [PATCH 09/16] API changes around key_import and key_export key_import will autodetect key_format and key_file_format. Only the expected key_type is required. key_export needs to have key_format and key_file_format explicitly given (obviously). It will get the key_type from the key. Change-Id: I6a8e04c886f6acd95dc124918606fbad992108c2 --- api/yaca/key.h | 45 +++++++++++++++++++++++++++++++++++---------- examples/encrypt_aes_gcm.c | 2 +- examples/key_exchange.c | 5 ++--- examples/test.c | 2 +- src/key.c | 8 ++++---- 5 files changed, 43 insertions(+), 19 deletions(-) diff --git a/api/yaca/key.h b/api/yaca/key.h index dd1dbe8..3a829d5 100644 --- a/api/yaca/key.h +++ b/api/yaca/key.h @@ -53,19 +53,29 @@ extern "C" { int yaca_key_get_bits(const yaca_key_h key); /** - * @brief yaca_key_import Imports a key from the arbitrary format. + * @brief yaca_key_import Imports a key. * - * @param[out] key Returned key (must be freed with yaca_key_free()). - * @param[in] key_file_fmt Format of the key file. - * @param[in] key_type Type of the key. - * @param[in] data Blob containing the key. - * @param[in] data_len Size of the blob. + * This function imports a key trying to match it to the key_type specified. + * It should autodetect both, key format and file format. + * + * For symmetric, IV and DES keys RAW binary format and BASE64 encoded + * binary format are supported. + * For asymmetric keys PEM and DER file formats are supported. + * + * Asymmetric keys can be in PKCS#1 or SSleay key formats (for RSA and + * DSA respectively). Asymmetric private keys can also be in PKCS#8 + * format. Additionally it is possible to import public RSA key from + * X509 certificate. + * + * @param[out] key Returned key (must be freed with yaca_key_free()). + * @param[in] key_type Type of the key. + * @param[in] data Blob containing the key. + * @param[in] data_len Size of the blob. * * @return 0 on success, negative on error. - * @see #yaca_key_fmt_e, #yaca_key_type_e, yaca_key_export(), yaca_key_free() + * @see #yaca_key_type_e, yaca_key_export(), yaca_key_free() */ int yaca_key_import(yaca_key_h *key, - yaca_key_file_fmt_e key_file_fmt, yaca_key_type_e key_type, const char *data, size_t data_len); @@ -73,16 +83,31 @@ int yaca_key_import(yaca_key_h *key, /** * @brief yaca_key_export Exports a key to arbitrary format. Export may fail if key is HW-based. * + * This function exports the key to an arbitrary key format and key file format. + * + * For key formats two values are allowed: + * - #YACA_KEY_FORMAT_DEFAULT: this is the only option possible in case of symmetric keys (or IV), + * for asymmetric keys it will choose PKCS#1 for RSA and SSLeay for DSA. + * - #YACA_KEY_FORMAT_PKCS8: this will only work for private asymmetric keys. + * + * The following file formats are supported: + * - #YACA_KEY_FILE_FORMAT_RAW: used only for symmetric, raw binary format + * - #YACA_KEY_FILE_FORMAT_BASE64: used only for symmetric, BASE64 encoded binary form + * - #YACA_KEY_FILE_FORMAT_PEM: used only for asymmetric, PEM file format + * - #YACA_KEY_FILE_FORMAT_DER: used only for asymmetric, DER file format + * * @param[in] key Key to be exported. - * @param[in] key_file_fmt Format of the key. + * @param[in] key_fmt Format of the key. + * @param[in] key_file_fmt Format of the key file. * @param[out] data Data, allocated by the library, containing exported key * (must be freed with yaca_free()). * @param[out] data_len Size of the output data. * * @return 0 on success, negative on error. - * @see #yaca_key_fmt_e, yaca_key_import(), yaca_key_free() + * @see #yaca_key_fmt_e, #yaca_key_file_fmt_e, yaca_key_import(), yaca_key_free() */ int yaca_key_export(const yaca_key_h key, + yaca_key_fmt_e key_fmt, yaca_key_file_fmt_e key_file_fmt, char **data, size_t *data_len); diff --git a/examples/encrypt_aes_gcm.c b/examples/encrypt_aes_gcm.c index 17c51ff..9bc60fe 100644 --- a/examples/encrypt_aes_gcm.c +++ b/examples/encrypt_aes_gcm.c @@ -71,7 +71,7 @@ void encrypt_decrypt_aes_gcm(void) goto clean; // generate and export aad? - ret = yaca_key_export(aad_key, YACA_KEY_FILE_FORMAT_RAW, &aad, &aad_len); + ret = yaca_key_export(aad_key, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_RAW, &aad, &aad_len); if (ret < 0) goto clean; diff --git a/examples/key_exchange.c b/examples/key_exchange.c index edbcd5d..9192679 100644 --- a/examples/key_exchange.c +++ b/examples/key_exchange.c @@ -67,8 +67,7 @@ void key_exchange_dh(void) if (1 != fread(buffer, size, 1, fp)) goto clean; - ret = yaca_key_import(&peer_key, - YACA_KEY_FILE_FORMAT_RAW, YACA_KEY_TYPE_DH_PUB, + ret = yaca_key_import(&peer_key, YACA_KEY_TYPE_DH_PUB, buffer, size); if (ret < 0) goto clean; @@ -124,7 +123,7 @@ void key_exchange_ecdh(void) if (1 != fread(buffer, size, 1, fp)) goto clean; - ret = yaca_key_import(&peer_key, YACA_KEY_FILE_FORMAT_RAW, YACA_KEY_TYPE_ECDH_PUB, buffer, size); + ret = yaca_key_import(&peer_key, YACA_KEY_TYPE_ECDH_PUB, buffer, size); if (ret < 0) goto clean; diff --git a/examples/test.c b/examples/test.c index a26148a..6f1bdf4 100644 --- a/examples/test.c +++ b/examples/test.c @@ -45,7 +45,7 @@ int main(int argc, char* argv[]) printf("done (%d)\n", ret); printf("Exporting key using CryptoAPI.. "); - ret = yaca_key_export(key, YACA_KEY_FILE_FORMAT_RAW, &k, &kl); + ret = yaca_key_export(key, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_RAW, &k, &kl); if (ret < 0) return ret; printf("done (%d)\n", ret); diff --git a/src/key.c b/src/key.c index eacaccd..1aba0d3 100644 --- a/src/key.c +++ b/src/key.c @@ -123,7 +123,6 @@ API int yaca_key_get_bits(const yaca_key_h key) } API int yaca_key_import(yaca_key_h *key, - yaca_key_file_fmt_e key_file_fmt, yaca_key_type_e key_type, const char *data, size_t data_len) @@ -131,9 +130,6 @@ API int yaca_key_import(yaca_key_h *key, if (key == NULL || data == NULL || data_len == 0) return YACA_ERROR_INVALID_ARGUMENT; - if (key_file_fmt != YACA_KEY_FILE_FORMAT_RAW) - return YACA_ERROR_NOT_IMPLEMENTED; - if (key_type == YACA_KEY_TYPE_SYMMETRIC) { struct yaca_key_simple_s *nk = NULL; @@ -164,6 +160,7 @@ API int yaca_key_import(yaca_key_h *key, } API int yaca_key_export(const yaca_key_h key, + yaca_key_fmt_e key_fmt, yaca_key_file_fmt_e key_file_fmt, char **data, size_t *data_len) @@ -175,6 +172,9 @@ API int yaca_key_export(const yaca_key_h key, if (data == NULL || data_len == NULL) return YACA_ERROR_INVALID_ARGUMENT; + if (key_fmt != YACA_KEY_FORMAT_DEFAULT) + return YACA_ERROR_NOT_IMPLEMENTED; + if (key_file_fmt != YACA_KEY_FILE_FORMAT_RAW) return YACA_ERROR_NOT_IMPLEMENTED; -- 2.7.4 From 782ce7f8fe5088539326dd9d92df30b9f6b03ded Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Thu, 28 Apr 2016 13:39:06 +0200 Subject: [PATCH 10/16] Small fixes in key.c Check for key length (non zero and dividable by 8). Asymmetric keys in the current state are INVALID_ARGUMENT. Change-Id: Ic7dd64fa86a485f11e52b83b2b82f710c4d55c80 --- src/key.c | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/src/key.c b/src/key.c index 1aba0d3..4006f5f 100644 --- a/src/key.c +++ b/src/key.c @@ -36,7 +36,7 @@ static inline void simple_key_sanity_check(const struct yaca_key_simple_s *key) { - assert(key->bits); + assert(key->bits != 0); assert(key->bits % 8 == 0); } @@ -206,7 +206,7 @@ API int yaca_key_gen(yaca_key_h *sym_key, struct yaca_key_simple_s *nk = NULL; size_t key_byte_len = key_bits / 8; - if (sym_key == NULL) + if (sym_key == NULL || key_bits % 8 != 0) return YACA_ERROR_INVALID_ARGUMENT; switch(key_type) @@ -215,21 +215,6 @@ API int yaca_key_gen(yaca_key_h *sym_key, 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: /* DH public key */ - case YACA_KEY_TYPE_DH_PRIV: /* DH private key */ - case YACA_KEY_TYPE_ECDSA_PUB: /* ECDSA public key */ - case YACA_KEY_TYPE_ECDSA_PRIV: /* ECDSA private key */ - case YACA_KEY_TYPE_ECDH_PUB: /* ECDH public key */ - case YACA_KEY_TYPE_ECDH_PRIV: /* ECDH 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 DH keys */ - case YACA_KEY_TYPE_PAIR_ECDSA: /* Pair of ECDSA keys */ - case YACA_KEY_TYPE_PAIR_ECDH: /* Pair of ECDH keys */ return YACA_ERROR_NOT_IMPLEMENTED; default: return YACA_ERROR_INVALID_ARGUMENT; @@ -418,16 +403,16 @@ API int yaca_key_derive_pbkdf2(const char *password, iter == 0 || key_bits == 0 || key == NULL) return YACA_ERROR_INVALID_ARGUMENT; - ret = digest_get_algorithm(algo, &md); - if (ret < 0) - return ret; - if (key_bits % 8) /* Key length must be multiple of 8-bits */ return YACA_ERROR_INVALID_ARGUMENT; if (key_byte_len > SIZE_MAX - sizeof(struct yaca_key_simple_s)) return YACA_ERROR_TOO_BIG_ARGUMENT; + ret = digest_get_algorithm(algo, &md); + if (ret < 0) + return ret; + nk = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_byte_len); if (nk == NULL) return YACA_ERROR_OUT_OF_MEMORY; -- 2.7.4 From f3cea1e67d96b68b600f4869009cf076a88fde7c Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Thu, 28 Apr 2016 13:55:04 +0200 Subject: [PATCH 11/16] Some TODOs added for things noticed Change-Id: I8683a77c3e50dea327cb5c10973d1fe310765470 --- api/yaca/types.h | 1 + 1 file changed, 1 insertion(+) diff --git a/api/yaca/types.h b/api/yaca/types.h index 5478a46..c467121 100644 --- a/api/yaca/types.h +++ b/api/yaca/types.h @@ -84,6 +84,7 @@ typedef enum { YACA_KEY_TYPE_ECDSA_PUB, /**< Elliptic Curve Digital Signature Algorithm public key */ YACA_KEY_TYPE_ECDSA_PRIV, /**< Elliptic Curve Digital Signature Algorithm private key */ + // TODO: ECDH might not exist as a separate key type, remove? YACA_KEY_TYPE_ECDH_PUB, /**< Elliptic Curve Diffie-Hellman public key */ YACA_KEY_TYPE_ECDH_PRIV, /**< Elliptic Curve Diffie-Hellman private key */ -- 2.7.4 From f64a279a8f0470812194f0a2515192c81d81bab8 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Mon, 25 Apr 2016 18:33:26 +0200 Subject: [PATCH 12/16] yaca_key_export() implementation for YACA_KEY_FORMAT_DEFAULT Change-Id: I946b1f862dd7f75d93372cea00deb6487ae35fb7 --- src/key.c | 248 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 231 insertions(+), 17 deletions(-) diff --git a/src/key.c b/src/key.c index 4006f5f..8373a4c 100644 --- a/src/key.c +++ b/src/key.c @@ -31,6 +31,8 @@ #include #include +#include +#include #include "internal.h" @@ -60,6 +62,219 @@ static inline void key_sanity_check(const yaca_key_h key) } #endif +int export_simple_raw(struct yaca_key_simple_s *simple_key, + char **data, + size_t *data_len) +{ + assert(simple_key != NULL); + assert(data != NULL); + assert(data_len != NULL); + + size_t key_len = simple_key->bits / 8; + + *data = yaca_malloc(key_len); + if (*data == NULL) { + ERROR_DUMP(YACA_ERROR_OUT_OF_MEMORY); + return YACA_ERROR_OUT_OF_MEMORY; + } + + memcpy(*data, simple_key->d, key_len); + *data_len = key_len; + + return 0; +} + +int export_simple_base64(struct yaca_key_simple_s *simple_key, + char **data, + size_t *data_len) +{ + assert(simple_key != NULL); + assert(data != NULL); + assert(data_len != NULL); + + int ret; + size_t key_len = simple_key->bits / 8; + BIO *b64; + BIO *mem; + char *bio_data; + long bio_data_len; + + b64 = BIO_new(BIO_f_base64()); + if (b64 == NULL) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + return ret; + } + + mem = BIO_new(BIO_s_mem()); + if (mem == NULL) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_bio; + } + + BIO_push(b64, mem); + + ret = BIO_write(b64, simple_key->d, key_len); + if (ret <= 0 || (unsigned)ret != key_len) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_bio; + } + + ret = BIO_flush(b64); + if (ret <= 0) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_bio; + } + + bio_data_len = BIO_get_mem_data(mem, &bio_data); + if (bio_data_len <= 0) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_bio; + } + + *data = yaca_malloc(bio_data_len); + if (*data == NULL) { + ret = YACA_ERROR_OUT_OF_MEMORY; + ERROR_DUMP(ret); + goto free_bio; + } + + memcpy(*data, bio_data, bio_data_len); + *data_len = bio_data_len; + ret = 0; + +free_bio: + BIO_free_all(b64); + + return ret; +} + +int export_evp(struct yaca_key_evp_s *evp_key, + yaca_key_file_fmt_e key_file_fmt, + char **data, + size_t *data_len) +{ + assert(evp_key != NULL); + assert(data != NULL); + assert(data_len != NULL); + + int ret = 0; + BIO *mem; + char *bio_data; + long bio_data_len; + + mem = BIO_new(BIO_s_mem()); + if (mem == NULL) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + return ret; + } + + switch (key_file_fmt) { + + case YACA_KEY_FILE_FORMAT_PEM: + switch (evp_key->key.type) { + + case YACA_KEY_TYPE_RSA_PRIV: + case YACA_KEY_TYPE_DSA_PRIV: + ret = PEM_write_bio_PrivateKey(mem, evp_key->evp, NULL, NULL, 0, NULL, NULL); + break; + + case YACA_KEY_TYPE_RSA_PUB: + case YACA_KEY_TYPE_DSA_PUB: + ret = PEM_write_bio_PUBKEY(mem, evp_key->evp); + break; + + case YACA_KEY_TYPE_DH_PRIV: + case YACA_KEY_TYPE_DH_PUB: + case YACA_KEY_TYPE_ECDSA_PRIV: + case YACA_KEY_TYPE_ECDSA_PUB: + case YACA_KEY_TYPE_ECDH_PRIV: + case YACA_KEY_TYPE_ECDH_PUB: + ret = YACA_ERROR_NOT_IMPLEMENTED; + goto free_bio; + + default: + ret = YACA_ERROR_INVALID_ARGUMENT; + goto free_bio; + } + + break; + + case YACA_KEY_FILE_FORMAT_DER: + switch (evp_key->key.type) { + + case YACA_KEY_TYPE_RSA_PRIV: + case YACA_KEY_TYPE_DSA_PRIV: + ret = i2d_PrivateKey_bio(mem, evp_key->evp); + break; + + case YACA_KEY_TYPE_RSA_PUB: + case YACA_KEY_TYPE_DSA_PUB: + ret = i2d_PUBKEY_bio(mem, evp_key->evp); + break; + + case YACA_KEY_TYPE_DH_PRIV: + case YACA_KEY_TYPE_DH_PUB: + case YACA_KEY_TYPE_ECDSA_PRIV: + case YACA_KEY_TYPE_ECDSA_PUB: + case YACA_KEY_TYPE_ECDH_PRIV: + case YACA_KEY_TYPE_ECDH_PUB: + ret = YACA_ERROR_NOT_IMPLEMENTED; + goto free_bio; + + default: + ret = YACA_ERROR_INVALID_ARGUMENT; + goto free_bio; + } + + break; + + default: + ret = YACA_ERROR_INVALID_ARGUMENT; + goto free_bio; + } + + if (ret <= 0) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_bio; + } + + ret = BIO_flush(mem); + if (ret <= 0) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_bio; + } + + bio_data_len = BIO_get_mem_data(mem, &bio_data); + if (bio_data_len <= 0) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_bio; + } + + *data = yaca_malloc(bio_data_len); + if (*data == NULL) { + ret = YACA_ERROR_OUT_OF_MEMORY; + ERROR_DUMP(ret); + goto free_bio; + } + + memcpy(*data, bio_data, bio_data_len); + *data_len = bio_data_len; + ret = 0; + +free_bio: + BIO_free_all(mem); + return ret; +} + struct yaca_key_simple_s *key_get_simple(const yaca_key_h key) { if (key == YACA_KEY_NULL) @@ -165,35 +380,34 @@ API int yaca_key_export(const yaca_key_h key, char **data, size_t *data_len) { - size_t byte_len; 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; - if (key_fmt != YACA_KEY_FORMAT_DEFAULT) - return YACA_ERROR_NOT_IMPLEMENTED; - - if (key_file_fmt != YACA_KEY_FILE_FORMAT_RAW) - return YACA_ERROR_NOT_IMPLEMENTED; - - if (simple_key != NULL) { + if (simple_key != NULL) simple_key_sanity_check(simple_key); - byte_len = simple_key->bits / 8; - *data = yaca_malloc(byte_len); - memcpy(*data, simple_key->d, byte_len); - *data_len = byte_len; + if (evp_key != NULL) + evp_key_sanity_check(evp_key); + + if (key_fmt == YACA_KEY_FORMAT_DEFAULT && + key_file_fmt == YACA_KEY_FILE_FORMAT_RAW && + simple_key != NULL) + return export_simple_raw(simple_key, data, data_len); - return 0; - } + if (key_fmt == YACA_KEY_FORMAT_DEFAULT && + key_file_fmt == YACA_KEY_FILE_FORMAT_BASE64 && + simple_key != NULL) + return export_simple_base64(simple_key, data, data_len); - if (evp_key != NULL) { - evp_key_sanity_check(evp_key); + if (key_fmt == YACA_KEY_FORMAT_DEFAULT && + evp_key != NULL) + return export_evp(evp_key, key_file_fmt, data, data_len); + if (key_fmt == YACA_KEY_FORMAT_PKCS8) return YACA_ERROR_NOT_IMPLEMENTED; - } return YACA_ERROR_INVALID_ARGUMENT; } -- 2.7.4 From d978aca4ccfbfe374bcd55784fbfad730a88fdb4 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Thu, 28 Apr 2016 18:30:29 +0200 Subject: [PATCH 13/16] yaca_key_import() basic implementation (symmetrical and RSA) Change-Id: I8a90a06326fabbbd8b013452c1d0797635451464 --- src/key.c | 316 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 291 insertions(+), 25 deletions(-) diff --git a/src/key.c b/src/key.c index 8373a4c..d6d95c4 100644 --- a/src/key.c +++ b/src/key.c @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -62,6 +63,277 @@ static inline void key_sanity_check(const yaca_key_h key) } #endif +int base64_decode_length(const char *data, size_t data_len, size_t *len) +{ + assert(data != NULL); + assert(data_len != 0); + assert(len != NULL); + + size_t padded = 0; + size_t tmp_len = data_len; + + if (data_len % 4 != 0) + return YACA_ERROR_INVALID_ARGUMENT; + + if (data[tmp_len - 1] == '=') { + padded = 1; + if (data[tmp_len - 2] == '=') + padded = 2; + } + + *len = data_len / 4 * 3 - padded; + return 0; +} + +#define TMP_BUF_LEN 512 + +int base64_decode(const char *data, size_t data_len, BIO **output) +{ + assert(data != NULL); + assert(data_len != 0); + assert(output != NULL); + + int ret; + BIO *b64 = NULL; + BIO *src = NULL; + BIO *dst = NULL; + char tmpbuf[TMP_BUF_LEN]; + size_t b64_len; + char *out; + long out_len; + + /* This is because of BIO_new_mem_buf() having its length param typed int */ + if (data_len > INT_MAX) + return YACA_ERROR_TOO_BIG_ARGUMENT; + + /* First phase of correctness checking, calculate expected output length */ + ret = base64_decode_length(data, data_len, &b64_len); + if (ret != 0) + return ret; + + b64 = BIO_new(BIO_f_base64()); + if (b64 == NULL) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + return ret; + } + + src = BIO_new_mem_buf(data, data_len); + if (src == NULL) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_bio; + } + + BIO_push(b64, src); + + dst = BIO_new(BIO_s_mem()); + if (dst == NULL) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_bio; + } + + BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); + + /* Try to decode */ + for(;;) { + ret = BIO_read(b64, tmpbuf, TMP_BUF_LEN); + if (ret < 0) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_bio; + } + + if (ret == 0) + break; + + if (BIO_write(dst, tmpbuf, ret) != ret) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_bio; + } + } + + BIO_flush(dst); + + /* Check wether the length of the decoded data is what we expected */ + out_len = BIO_get_mem_data(dst, &out); + if (out_len < 0) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_bio; + } + if ((size_t)out_len != b64_len) { + ret = YACA_ERROR_INVALID_ARGUMENT; + goto free_bio; + } + + *output = dst; + dst = NULL; + ret = 0; + +free_bio: + BIO_free_all(b64); + BIO_free_all(dst); + + return ret; +} + +int import_simple(yaca_key_h *key, + yaca_key_type_e key_type, + const char *data, + size_t data_len) +{ + assert(key != NULL); + assert(data != NULL); + assert(data_len != 0); + + int ret; + BIO *decoded = NULL; + const char *key_data; + size_t key_data_len; + struct yaca_key_simple_s *nk = NULL; + + ret = base64_decode(data, data_len, &decoded); + if (ret == 0) { + /* Conversion successfull, get the BASE64 */ + long len = BIO_get_mem_data(decoded, &key_data); + if (len <= 0 || key_data == NULL) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + return ret; + } + key_data_len = len; + } else if (ret == YACA_ERROR_INVALID_ARGUMENT) { + /* This was not BASE64 or it was corrupted, treat as RAW */ + key_data_len = data_len; + key_data = data; + } else { + /* Some other, possibly unrecoverable error, give up */ + return ret; + } + + if (key_data_len > SIZE_MAX - sizeof(struct yaca_key_simple_s)) { + ret = YACA_ERROR_TOO_BIG_ARGUMENT; + goto out; + } + + nk = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_data_len); + if (nk == NULL) { + ret = YACA_ERROR_OUT_OF_MEMORY; + goto out; + } + + memcpy(nk->d, key_data, key_data_len); + nk->bits = key_data_len * 8; + nk->key.type = key_type; + + *key = (yaca_key_h)nk; + ret = 0; + +out: + BIO_free_all(decoded); + return ret; +} + +int import_evp(yaca_key_h *key, + yaca_key_type_e key_type, + const char *data, + size_t data_len) +{ + assert(key != NULL); + assert(data != NULL); + assert(data_len != 0); + + BIO *src = NULL; + EVP_PKEY *pkey = NULL; + bool private; + yaca_key_type_e type; + struct yaca_key_evp_s *nk = NULL; + + /* Neither PEM nor DER will ever be shorter then 4 bytes (12 seems + * to be minimum for DER, much more for PEM). This is just to make + * sure we have at least 4 bytes for strncmp() below. + */ + if (data_len < 4) + return YACA_ERROR_INVALID_ARGUMENT; + + /* This is because of BIO_new_mem_buf() having its length param typed int */ + if (data_len > INT_MAX) + return YACA_ERROR_TOO_BIG_ARGUMENT; + + src = BIO_new_mem_buf(data, data_len); + if (src == NULL) { + ERROR_DUMP(YACA_ERROR_INTERNAL); + return YACA_ERROR_INTERNAL; + } + + /* Possible PEM */ + if (strncmp("----", data, 4) == 0) { + if (pkey == NULL) { + BIO_reset(src); + pkey = PEM_read_bio_PrivateKey(src, NULL, NULL, NULL); + private = true; + } + + if (pkey == NULL) { + BIO_reset(src); + pkey = PEM_read_bio_PUBKEY(src, NULL, NULL, NULL); + private = false; + } + } + /* Possible DER */ + else { + if (pkey == NULL) { + BIO_reset(src); + pkey = d2i_PrivateKey_bio(src, NULL); + private = true; + } + + if (pkey == NULL) { + BIO_reset(src); + pkey = d2i_PUBKEY_bio(src, NULL); + private = false; + } + } + + BIO_free(src); + + if (pkey == NULL) + return YACA_ERROR_INVALID_ARGUMENT; + + switch (EVP_PKEY_type(pkey->type)) { + case EVP_PKEY_RSA: + type = private ? YACA_KEY_TYPE_RSA_PRIV : YACA_KEY_TYPE_RSA_PUB; + break; + + case EVP_PKEY_DSA: + type = private ? YACA_KEY_TYPE_DSA_PRIV : YACA_KEY_TYPE_DSA_PUB; + break; + + case EVP_PKEY_EC: + type = private ? YACA_KEY_TYPE_ECDSA_PRIV : YACA_KEY_TYPE_ECDSA_PUB; + break; + + default: + return YACA_ERROR_INVALID_ARGUMENT; + } + + if (type != key_type) + return YACA_ERROR_INVALID_ARGUMENT; + + nk = yaca_zalloc(sizeof(struct yaca_key_evp_s)); + if (nk == NULL) + return YACA_ERROR_OUT_OF_MEMORY; + + nk->evp = pkey; + *key = (yaca_key_h)nk; + (*key)->type = type; + + return 0; +} + int export_simple_raw(struct yaca_key_simple_s *simple_key, char **data, size_t *data_len) @@ -114,6 +386,7 @@ int export_simple_base64(struct yaca_key_simple_s *simple_key, } BIO_push(b64, mem); + BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); ret = BIO_write(b64, simple_key->d, key_len); if (ret <= 0 || (unsigned)ret != key_len) { @@ -345,32 +618,25 @@ API int yaca_key_import(yaca_key_h *key, if (key == NULL || data == NULL || data_len == 0) return YACA_ERROR_INVALID_ARGUMENT; - if (key_type == YACA_KEY_TYPE_SYMMETRIC) { - struct yaca_key_simple_s *nk = NULL; - - if (data_len > SIZE_MAX - sizeof(struct yaca_key_simple_s)) - return YACA_ERROR_TOO_BIG_ARGUMENT; - - nk = yaca_zalloc(sizeof(struct yaca_key_simple_s) + data_len); - if (nk == NULL) - return YACA_ERROR_OUT_OF_MEMORY; - - memcpy(nk->d, data, data_len); /* TODO: CRYPTO_/EVP_... */ - nk->bits = data_len * 8; - nk->key.type = key_type; - - *key = (yaca_key_h)nk; - return 0; - } - - if (key_type == YACA_KEY_TYPE_DES) { - // TODO: ... - return YACA_ERROR_NOT_IMPLEMENTED; - } - - /* if (...) */ { - // TODO: all the other key types + switch (key_type) { + case YACA_KEY_TYPE_SYMMETRIC: + case YACA_KEY_TYPE_IV: + return import_simple(key, key_type, data, data_len); + case YACA_KEY_TYPE_RSA_PUB: + case YACA_KEY_TYPE_RSA_PRIV: + return import_evp(key, key_type, data, data_len); + case YACA_KEY_TYPE_DES: + case YACA_KEY_TYPE_DSA_PUB: + case YACA_KEY_TYPE_DSA_PRIV: + case YACA_KEY_TYPE_DH_PUB: + case YACA_KEY_TYPE_DH_PRIV: + case YACA_KEY_TYPE_ECDSA_PUB: + case YACA_KEY_TYPE_ECDSA_PRIV: + case YACA_KEY_TYPE_ECDH_PUB: + case YACA_KEY_TYPE_ECDH_PRIV: return YACA_ERROR_NOT_IMPLEMENTED; + default: + return YACA_ERROR_INVALID_ARGUMENT; } } -- 2.7.4 From 477f87afb5ee0d5f3f74a42ae2c15872108b8bb5 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Tue, 26 Apr 2016 15:04:30 +0200 Subject: [PATCH 14/16] key_import/key_export example Change-Id: Ia638fdc60c88684163dc6afe3aa3e83d65684950 --- examples/CMakeLists.txt | 1 + examples/key_import_export.c | 231 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 232 insertions(+) create mode 100644 examples/key_import_export.c diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 9048331..fe238d2 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -50,6 +50,7 @@ BUILD_EXAMPLE("yaca-example-encrypt-gcm" encrypt_aes_gcm.c) BUILD_EXAMPLE("yaca-example-sign" sign.c) BUILD_EXAMPLE("yaca-example-key-exchange" key_exchange.c) BUILD_EXAMPLE("yaca-example-test" test.c) +BUILD_EXAMPLE("yaca-example-key-impexp" key_import_export.c) INSTALL(FILES ${COMMON_SOURCES} DESTINATION ${EXAMPLES_DIR}) diff --git a/examples/key_import_export.c b/examples/key_import_export.c new file mode 100644 index 0000000..fba4664 --- /dev/null +++ b/examples/key_import_export.c @@ -0,0 +1,231 @@ +/* + * 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 + */ + +/** + * @file key_import_export.c + * @brief + */ + +#include + +#include "misc.h" + +#include +#include +#include +#include +#include + +void key_import_export_sym(yaca_key_h sym) +{ + int ret; + + char *raw = NULL; + size_t raw_len; + char *b64= NULL; + size_t b64_len; + + yaca_key_h raw_imported = YACA_KEY_NULL; + yaca_key_h b64_imported = YACA_KEY_NULL; + + + ret = yaca_key_export(sym, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_BASE64, &b64, &b64_len); + if (ret != 0) + return; + ret = yaca_key_import(&b64_imported, YACA_KEY_TYPE_SYMMETRIC, b64, b64_len); + if (ret != 0) + goto free; + + printf("\n\t***** BASE64 exported key: *****\n%*s\n", (int)b64_len, b64); + yaca_free(b64); + b64 = NULL; + + ret = yaca_key_export(b64_imported, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_BASE64, &b64, &b64_len); + if (ret != 0) + goto free; + + printf("\t***** BASE64 imported key: *****\n%*s\n", (int)b64_len, b64); + + + ret = yaca_key_export(sym, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_RAW, &raw, &raw_len); + if (ret != 0) + goto free; + ret = yaca_key_import(&raw_imported, YACA_KEY_TYPE_SYMMETRIC, raw, raw_len); + if (ret != 0) + goto free; + + dump_hex(raw, raw_len, "\n\t***** RAW exported key: *****"); + yaca_free(raw); + raw = NULL; + + ret = yaca_key_export(raw_imported, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_RAW, &raw, &raw_len); + if (ret != 0) + goto free; + + dump_hex(raw, raw_len, "\t***** RAW imported key: *****"); + +free: + yaca_key_free(raw_imported); + yaca_key_free(b64_imported); + yaca_free(raw); + yaca_free(b64); +} + +void key_import_export_rsa(yaca_key_h priv, yaca_key_h pub) +{ + int ret; + + char *pem_prv = NULL; + size_t pem_prv_len; + char *der_prv = NULL; + size_t der_prv_len; + + char *pem_pub = NULL; + size_t pem_pub_len; + char *der_pub = NULL; + size_t der_pub_len; + + yaca_key_h pem_prv_imported = YACA_KEY_NULL; + yaca_key_h der_prv_imported = YACA_KEY_NULL; + yaca_key_h pem_pub_imported = YACA_KEY_NULL; + yaca_key_h der_pub_imported = YACA_KEY_NULL; + + + /* PEM private */ + + ret = yaca_key_export(priv, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_PEM, &pem_prv, &pem_prv_len); + if (ret != 0) + return; + ret = yaca_key_import(&pem_prv_imported, YACA_KEY_TYPE_RSA_PRIV, pem_prv, pem_prv_len); + if (ret != 0) + goto free; + + printf("\n\t***** PEM exported private key: *****\n%*s", (int)pem_prv_len, pem_prv); + yaca_free(pem_prv); + pem_prv = NULL; + + ret = yaca_key_export(pem_prv_imported, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_PEM, &pem_prv, &pem_prv_len); + if (ret != 0) + goto free; + + printf("\t***** PEM imported private key: *****\n%*s", (int)pem_prv_len, pem_prv); + + + /* DER private */ + + ret = yaca_key_export(priv, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_DER, &der_prv, &der_prv_len); + if (ret != 0) + goto free; + ret = yaca_key_import(&der_prv_imported, YACA_KEY_TYPE_RSA_PRIV, der_prv, der_prv_len); + if (ret != 0) + goto free; + + dump_hex(der_prv, der_prv_len, "\n\t***** DER exported private key: *****"); + yaca_free(der_prv); + der_prv = NULL; + + ret = yaca_key_export(der_prv_imported, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_DER, &der_prv, &der_prv_len); + if (ret != 0) + goto free; + + dump_hex(der_prv, der_prv_len, "\t***** DER imported private key: *****"); + + + /* PEM public */ + + ret = yaca_key_export(pub, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_PEM, &pem_pub, &pem_pub_len); + if (ret != 0) + goto free; + ret = yaca_key_import(&pem_pub_imported, YACA_KEY_TYPE_RSA_PUB, pem_pub, pem_pub_len); + if (ret != 0) + goto free; + + printf("\n\t***** PEM exported public key: *****\n%*s", (int)pem_pub_len, pem_pub); + yaca_free(pem_pub); + pem_pub = NULL; + + ret = yaca_key_export(pem_pub_imported, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_PEM, &pem_pub, &pem_pub_len); + if (ret != 0) + goto free; + + printf("\t***** PEM imported public key: *****\n%*s", (int)pem_pub_len, pem_pub); + + + /* DER public */ + + ret = yaca_key_export(pub, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_DER, &der_pub, &der_pub_len); + if (ret != 0) + goto free; + ret = yaca_key_import(&der_pub_imported, YACA_KEY_TYPE_RSA_PUB, der_pub, der_pub_len); + if (ret != 0) + goto free; + + dump_hex(der_pub, der_pub_len, "\n\t***** DER exported public key: *****"); + yaca_free(der_pub); + der_pub = NULL; + + ret = yaca_key_export(der_pub_imported, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_DER, &der_pub, &der_pub_len); + if (ret != 0) + goto free; + + dump_hex(der_pub, der_pub_len, "\t***** DER imported public key: *****"); + +free: + yaca_key_free(der_pub_imported); + yaca_key_free(pem_pub_imported); + yaca_key_free(der_prv_imported); + yaca_key_free(pem_prv_imported); + yaca_free(der_pub); + yaca_free(pem_pub); + yaca_free(der_prv); + yaca_free(pem_prv); +} + +int main() +{ + yaca_key_h sym; + yaca_key_h rsa_priv; + yaca_key_h rsa_pub; + int ret; + + ret = yaca_init(); + if (ret != 0) + return ret; + + yaca_error_set_debug_func(debug_func); + + ret = yaca_key_gen(&sym, YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_1024BIT); + if (ret != 0) + goto exit; + + ret = yaca_key_gen_pair(&rsa_priv, &rsa_pub, YACA_KEY_TYPE_PAIR_RSA, YACA_KEY_1024BIT); + if (ret != 0) + goto free_sym; + + key_import_export_sym(sym); + key_import_export_rsa(rsa_priv, rsa_pub); + + yaca_key_free(rsa_priv); + yaca_key_free(rsa_pub); +free_sym: + yaca_key_free(sym); +exit: + yaca_exit(); + + return ret; +} -- 2.7.4 From 3b7c99c08bd52ae2d1dcfa3b2d1c53ec3b782268 Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Thu, 5 May 2016 11:45:46 +0200 Subject: [PATCH 15/16] Make yaca GCC 5 compatibile GCC 5 issues a warning for __FUNCTION__. Use __func__ instead. Change-Id: I3d37621c8384e4f229140bfc3af8c92f81058ff5 --- src/internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/internal.h b/src/internal.h index 5bff4f1..119728f 100644 --- a/src/internal.h +++ b/src/internal.h @@ -101,6 +101,6 @@ 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); void error_dump(const char *file, int line, const char *function, int code); -#define ERROR_DUMP(code) error_dump(__FILE__, __LINE__, __FUNCTION__, (code)) +#define ERROR_DUMP(code) error_dump(__FILE__, __LINE__, __func__, (code)) #endif -- 2.7.4 From 4d45f43effc56dc4d826400ebdd042fb2796297a Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Fri, 6 May 2016 15:14:22 +0200 Subject: [PATCH 16/16] Remove YACA_ERROR_NOT_SUPPORTED Change-Id: I3f6b9cf907fc4fb4e0dd6dd84452f1448e223e65 --- api/yaca/error.h | 7 +++--- src/crypto.c | 23 ++++++------------- src/sign.c | 68 ++++++++++++++++++-------------------------------------- 3 files changed, 32 insertions(+), 66 deletions(-) diff --git a/api/yaca/error.h b/api/yaca/error.h index eaca621..944d8a3 100644 --- a/api/yaca/error.h +++ b/api/yaca/error.h @@ -41,10 +41,9 @@ enum __yaca_error_code { YACA_ERROR_INVALID_ARGUMENT = -1, YACA_ERROR_NOT_IMPLEMENTED = -2, YACA_ERROR_INTERNAL = -3, - YACA_ERROR_NOT_SUPPORTED = -4, - YACA_ERROR_TOO_BIG_ARGUMENT = -5, - YACA_ERROR_OUT_OF_MEMORY = -6, - YACA_ERROR_SIGNATURE_INVALID = -7 + YACA_ERROR_TOO_BIG_ARGUMENT = -4, + YACA_ERROR_OUT_OF_MEMORY = -5, + YACA_ERROR_SIGNATURE_INVALID = -6 }; // TODO disable debug function in release? diff --git a/src/crypto.c b/src/crypto.c index 734dba5..650bdcf 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -84,39 +84,30 @@ API int yaca_rand_bytes(char *data, size_t data_len) return YACA_ERROR_INVALID_ARGUMENT; ret = RAND_bytes((unsigned char *)data, data_len); - if (ret == 1) - return 0; - - if (ret == -1) - ret = YACA_ERROR_NOT_SUPPORTED; - else + if (ret != 1) { ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + return ret; + } - ERROR_DUMP(ret); - return ret; + return 0; } API int yaca_ctx_set_param(yaca_ctx_h ctx, yaca_ex_param_e param, const void *value, size_t value_len) { - if (ctx == YACA_CTX_NULL) + if (ctx == YACA_CTX_NULL || ctx->set_param == NULL) return YACA_ERROR_INVALID_ARGUMENT; - if (ctx->set_param == NULL) - return YACA_ERROR_NOT_SUPPORTED; - return ctx->set_param(ctx, param, value, value_len); } API int yaca_ctx_get_param(const yaca_ctx_h ctx, yaca_ex_param_e param, void **value, size_t *value_len) { - if (ctx == YACA_CTX_NULL) + if (ctx == YACA_CTX_NULL || ctx->get_param == NULL) return YACA_ERROR_INVALID_ARGUMENT; - if (ctx->get_param == NULL) - return YACA_ERROR_NOT_SUPPORTED; - return ctx->get_param(ctx, param, value, value_len); } diff --git a/src/sign.c b/src/sign.c index 0c789bc..24fe7ac 100644 --- a/src/sign.c +++ b/src/sign.c @@ -180,11 +180,6 @@ API int yaca_sign_init(yaca_ctx_h *ctx, } ret = EVP_DigestSignInit(nc->mdctx, NULL, md, NULL, pkey); - if (ret == -2) { - ret = YACA_ERROR_NOT_SUPPORTED; - ERROR_DUMP(ret); - goto ctx; - } if (ret != 1) { ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); @@ -219,16 +214,13 @@ API int yaca_sign_update(yaca_ctx_h ctx, return YACA_ERROR_INVALID_ARGUMENT; ret = EVP_DigestSignUpdate(c->mdctx, data, data_len); - if (ret == 1) - return 0; - - if (ret == -2) - ret = YACA_ERROR_NOT_SUPPORTED; - else + if (ret != 1) { ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + return ret; + } - ERROR_DUMP(ret); - return ret; + return 0; } API int yaca_sign_final(yaca_ctx_h ctx, @@ -243,16 +235,13 @@ API int yaca_sign_final(yaca_ctx_h ctx, return YACA_ERROR_INVALID_ARGUMENT; ret = EVP_DigestSignFinal(c->mdctx, (unsigned char *)mac, mac_len); - if(ret == 1) - return 0; - - if (ret == -2) - ret = YACA_ERROR_NOT_SUPPORTED; - else + if(ret != 1) { ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + return ret; + } - ERROR_DUMP(ret); - return ret; + return 0; } API int yaca_verify_init(yaca_ctx_h *ctx, @@ -323,11 +312,6 @@ API int yaca_verify_init(yaca_ctx_h *ctx, goto ctx; } - if (ret == -2) { - ret = YACA_ERROR_NOT_SUPPORTED; - ERROR_DUMP(ret); - goto ctx; - } if (ret != 1) { ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); @@ -372,16 +356,13 @@ API int yaca_verify_update(yaca_ctx_h ctx, return YACA_ERROR_INVALID_ARGUMENT; } - if (ret == 1) - return 0; - - if (ret == -2) - ret = YACA_ERROR_NOT_SUPPORTED; - else + if (ret != 1) { ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + return ret; + } - ERROR_DUMP(ret); - return ret; + return 0; } API int yaca_verify_final(yaca_ctx_h ctx, @@ -402,19 +383,16 @@ API int yaca_verify_final(yaca_ctx_h ctx, ret = EVP_DigestSignFinal(c->mdctx, (unsigned char *)mac_cmp, &mac_cmp_len); - if (ret == 1) { - if (mac_len != mac_cmp_len || CRYPTO_memcmp(mac, mac_cmp, mac_len) != 0) - return YACA_ERROR_SIGNATURE_INVALID; - return 0; + if (ret != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + return ret; } - if (ret == -2) - ret = YACA_ERROR_NOT_SUPPORTED; - else - ret = YACA_ERROR_INTERNAL; + if (mac_len != mac_cmp_len || CRYPTO_memcmp(mac, mac_cmp, mac_len) != 0) + return YACA_ERROR_SIGNATURE_INVALID; - ERROR_DUMP(ret); - return ret; + return 0; case OP_VERIFY_ASYMMETRIC: ret = EVP_DigestVerifyFinal(c->mdctx, (unsigned char *)mac, @@ -424,8 +402,6 @@ API int yaca_verify_final(yaca_ctx_h ctx, if (ret == 0) ret = YACA_ERROR_SIGNATURE_INVALID; - else if (ret == -2) - ret = YACA_ERROR_NOT_SUPPORTED; else ret = YACA_ERROR_INTERNAL; -- 2.7.4