From 50fb46378e4a4453befd684bab9b8dd14e7d178f Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Mon, 23 May 2016 10:00:17 +0200 Subject: [PATCH 01/16] Fix sign ctx cleanup Change-Id: I791a1be4e2d5a32bcc2f11c24ebd19d5ba32fcc8 --- src/sign.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/sign.c b/src/sign.c index 0b6d8f7..8cff08c 100644 --- a/src/sign.c +++ b/src/sign.c @@ -315,19 +315,16 @@ API int yaca_sign_init(yaca_ctx_h *ctx, if (ret != 1) { ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); - goto ctx; + goto free_ctx; } *ctx = (yaca_ctx_h)nc; ret = 0; -ctx: - if (ret != 0) - EVP_MD_CTX_destroy(nc->mdctx); free_ctx: if (ret != 0) - yaca_free(nc); + yaca_ctx_free((yaca_ctx_h)nc); free_key: EVP_PKEY_free(pkey); @@ -442,25 +439,22 @@ API int yaca_verify_init(yaca_ctx_h *ctx, break; default: ret = YACA_ERROR_INVALID_ARGUMENT; - goto ctx; + goto free_ctx; } if (ret != 1) { ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); - goto ctx; + goto free_ctx; } *ctx = (yaca_ctx_h)nc; ret = 0; -ctx: - if (ret != 0) - EVP_MD_CTX_destroy(nc->mdctx); free_ctx: if (ret != 0) - yaca_free(nc); + yaca_ctx_free((yaca_ctx_h)nc); free_key: EVP_PKEY_free(pkey); -- 2.7.4 From b3d779e2f248687764d9e552c144fd131b23201f Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Wed, 18 May 2016 09:33:14 +0200 Subject: [PATCH 02/16] CMAC implementation Change-Id: Ie6c0f5a83db902cddcb029d9140c12351b17d4e6 --- src/sign.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/src/sign.c b/src/sign.c index 8cff08c..4e119be 100644 --- a/src/sign.c +++ b/src/sign.c @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -331,6 +332,97 @@ free_key: return ret; } +API int yaca_sign_cmac_init(yaca_ctx_h *ctx, + yaca_enc_algo_e algo, + const yaca_key_h key) +{ + struct yaca_sign_ctx_s *nc = NULL; + CMAC_CTX* cmac_ctx = NULL; + const EVP_CIPHER* cipher = NULL; + EVP_PKEY *pkey = NULL; + int ret; + + if (ctx == NULL || key == NULL || + (key->type != YACA_KEY_TYPE_SYMMETRIC && key->type != YACA_KEY_TYPE_DES)) + return YACA_ERROR_INVALID_ARGUMENT; + + const struct yaca_key_simple_s *simple_key = key_get_simple(key); + + // the type is ok so we should be able to extract simple key + assert(simple_key != NULL); + + nc = yaca_zalloc(sizeof(struct yaca_sign_ctx_s)); + if (nc == NULL) { + return YACA_ERROR_OUT_OF_MEMORY; + } + + nc->op_type = OP_SIGN; + nc->ctx.type = YACA_CTX_SIGN; + nc->ctx.ctx_destroy = destroy_sign_context; + nc->ctx.get_output_length = get_sign_output_length; + + ret = encrypt_get_algorithm(algo, YACA_BCM_CBC, simple_key->bits, &cipher); + if (ret != 0) { + goto free_ctx; + } + + // create and initialize low level CMAC context + cmac_ctx = CMAC_CTX_new(); + if (cmac_ctx == NULL) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_ctx; + } + + if (CMAC_Init(cmac_ctx, simple_key->d, simple_key->bits/8, cipher, NULL) != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + // TODO refactor error handling: use single cleanup label + goto free_cmac_ctx; + } + + // create key and assign CMAC context to it + pkey = EVP_PKEY_new(); + if (!pkey) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_cmac_ctx; + } + + if (EVP_PKEY_assign(pkey, EVP_PKEY_CMAC, cmac_ctx) != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_pkey; + } + // TODO refactor error handling: set cmac_ctx to NULL + + nc->mdctx = EVP_MD_CTX_create(); + if (nc->mdctx == NULL) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_pkey; + } + + if (EVP_DigestSignInit(nc->mdctx, NULL, NULL, NULL, pkey) != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_pkey; + } + // TODO refactor error handling: set mdctx to NULL, set pkey to NULL + + *ctx = (yaca_ctx_h)nc; + return 0; + +free_pkey: + EVP_PKEY_free(pkey); +free_cmac_ctx: + CMAC_CTX_free(cmac_ctx); +free_ctx: + yaca_ctx_free((yaca_ctx_h)nc); + + return ret; +} + API int yaca_sign_update(yaca_ctx_h ctx, const char *data, size_t data_len) -- 2.7.4 From eedb7a5848734a15989b023c5a6ef2a2d98bdf7d Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Wed, 18 May 2016 11:33:33 +0200 Subject: [PATCH 03/16] CMAC example Change-Id: I2b17f9375e3cfd14048bb639b84f3627a13bb73f --- examples/sign.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/examples/sign.c b/examples/sign.c index 5612ead..1981b27 100644 --- a/examples/sign.c +++ b/examples/sign.c @@ -150,9 +150,8 @@ finish: void sign_verify_cmac(void) { - // TODO rewrite it -#if 0 - char* signature = NULL; + char *signature1 = NULL; + char *signature2 = NULL; size_t signature_len; yaca_ctx_h ctx = YACA_CTX_NULL; @@ -163,8 +162,7 @@ void sign_verify_cmac(void) return; // SIGN - // TODO: CMAC must extract the key length to select the proper evp (EVP_aes_XXX_cbc()) it should be documented - if (yaca_sign_init(&ctx, YACA_DIGEST_CMAC, key) != 0) + if (yaca_sign_cmac_init(&ctx, YACA_ENC_AES, key) != 0) goto finish; if (yaca_sign_update(ctx, lorem4096, LOREM4096_SIZE)) @@ -173,35 +171,44 @@ void sign_verify_cmac(void) if (yaca_get_sign_length(ctx, &signature_len) != 0) goto finish; - if ((signature = yaca_malloc(signature_len)) == NULL) + if ((signature1 = yaca_malloc(signature_len)) == NULL) goto finish; - if (yaca_sign_final(ctx, signature, &signature_len)) + if (yaca_sign_final(ctx, signature1, &signature_len)) goto finish; - dump_hex(signature, signature_len, "CMAC Signature of lorem4096:"); + dump_hex(signature1, signature_len, "CMAC Signature of lorem4096:"); // CLEANUP yaca_ctx_free(ctx); ctx = YACA_CTX_NULL; // VERIFY - if (yaca_verify_init(&ctx, YACA_DIGEST_CMAC, key) != 0) + if (yaca_sign_cmac_init(&ctx, YACA_ENC_AES, key) != 0) goto finish; - if (yaca_verify_update(ctx, lorem4096, LOREM4096_SIZE) != 0) + if (yaca_sign_update(ctx, lorem4096, LOREM4096_SIZE)) goto finish; - if (yaca_verify_final(ctx, signature, signature_len) != 0) + if (yaca_get_sign_length(ctx, &signature_len) != 0) + goto finish; + + if ((signature2 = yaca_malloc(signature_len)) == NULL) + goto finish; + + if (yaca_sign_final(ctx, signature2, &signature_len)) + goto finish; + + if (yaca_memcmp(signature1, signature2, signature_len) != 0) printf("CMAC verification failed\n"); else printf("CMAC verification succesful\n"); finish: - yaca_free(signature); + yaca_free(signature1); + yaca_free(signature2); yaca_key_free(key); yaca_ctx_free(ctx); -#endif } int main() -- 2.7.4 From 6c04ec20579c2ca54ef70aa422b12b6bc8171c49 Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Mon, 23 May 2016 12:33:52 +0200 Subject: [PATCH 04/16] Use "!= 0" instead of "< 0" when handling yaca errors Change-Id: I8b298d9125d84b85c36cbde9ada9dc48af4e9402 --- examples/digest.c | 10 +++++----- examples/encrypt.c | 2 +- examples/encrypt_aes_gcm.c | 30 +++++++++++++++--------------- examples/key_exchange.c | 18 +++++++++--------- examples/seal.c | 2 +- examples/sign.c | 2 +- src/digest.c | 2 +- src/encrypt.c | 2 +- src/key.c | 2 +- src/sign.c | 2 +- src/simple.c | 6 +++--- 11 files changed, 39 insertions(+), 39 deletions(-) diff --git a/examples/digest.c b/examples/digest.c index 68c6bcb..9c68be3 100644 --- a/examples/digest.c +++ b/examples/digest.c @@ -39,7 +39,7 @@ void digest_simple(void) ret = yaca_digest_calc(YACA_DIGEST_SHA256, lorem1024, 1024, &digest, &digest_len); - if (ret < 0) + if (ret != 0) return; dump_hex(digest, digest_len, "Message digest: "); @@ -53,11 +53,11 @@ void digest_advanced(void) yaca_ctx_h ctx; ret = yaca_digest_init(&ctx, YACA_DIGEST_SHA256); - if (ret < 0) + if (ret != 0) return; ret = yaca_digest_update(ctx, lorem1024, 1024); - if (ret < 0) + if (ret != 0) goto exit_ctx; size_t digest_len; @@ -69,7 +69,7 @@ void digest_advanced(void) char digest[digest_len]; ret = yaca_digest_final(ctx, digest, &digest_len); - if (ret < 0) + if (ret != 0) goto exit_ctx; dump_hex(digest, digest_len, "Message digest: "); @@ -84,7 +84,7 @@ int main() yaca_debug_set_error_cb(debug_func); int ret = yaca_init(); - if (ret < 0) + if (ret != 0) return ret; digest_simple(); diff --git a/examples/encrypt.c b/examples/encrypt.c index c01ab04..d436f52 100644 --- a/examples/encrypt.c +++ b/examples/encrypt.c @@ -186,7 +186,7 @@ int main() yaca_debug_set_error_cb(debug_func); int ret = yaca_init(); - if (ret < 0) + if (ret != 0) return ret; yaca_enc_algo_e algo = YACA_ENC_AES; diff --git a/examples/encrypt_aes_gcm.c b/examples/encrypt_aes_gcm.c index 1e61bc3..c89127e 100644 --- a/examples/encrypt_aes_gcm.c +++ b/examples/encrypt_aes_gcm.c @@ -58,22 +58,22 @@ void encrypt_decrypt_aes_gcm(void) /// Key generation ret = yaca_key_gen(&key, YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_256BIT); // key_type, key_len, *key ? looks imo much better - if (ret < 0) + if (ret != 0) goto clean; // use YACA_KEY_IV_128BIT & YACA_KEY_TYPE_IV or maybe YACA_KEY_128BIT & YACA_KEY_TYPE_SYMMETRIC ? ret = yaca_key_gen(&iv, YACA_KEY_TYPE_IV, YACA_KEY_IV_128BIT); - if (ret < 0) + if (ret != 0) goto clean; // use YACA_KEY_128BIT & YACA_KEY_TYPE_SYMMETRIC or maybe add YACA_KEY_AAD_128BIT & YACA_KEY_TYPE_AAD ? ret = yaca_key_gen(&aad_key, YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_UNSAFE_128BIT); - if (ret < 0) + if (ret != 0) goto clean; // generate and export aad? ret = yaca_key_export(aad_key, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_RAW, NULL, &aad, &aad_len); - if (ret < 0) + if (ret != 0) goto clean; /// Encryption @@ -81,11 +81,11 @@ void encrypt_decrypt_aes_gcm(void) size_t len; ret = yaca_encrypt_init(&ctx, YACA_ENC_AES, YACA_BCM_GCM, key, iv); - if (ret < 0) + if (ret != 0) goto clean; ret = yaca_ctx_set_param(ctx, YACA_PARAM_GCM_AAD, aad, aad_len); - if (ret < 0) + if (ret != 0) goto clean; ret = yaca_get_output_length(ctx, LOREM4096_SIZE, &ciphertext_len); @@ -102,19 +102,19 @@ void encrypt_decrypt_aes_gcm(void) goto clean; ret = yaca_encrypt_update(ctx, lorem4096, LOREM4096_SIZE, ciphertext, &len); - if (ret < 0) + if (ret != 0) goto clean; ciphertext_len = len; ret = yaca_encrypt_final(ctx, ciphertext + len, &len); - if (ret < 0) + if (ret != 0) goto clean; ciphertext_len += len; ret = yaca_ctx_get_param(ctx, YACA_PARAM_GCM_TAG, (void*)&tag, &tag_len); - if (ret < 0) + if (ret != 0) goto clean; dump_hex(ciphertext, 16, "Encrypted data (16 of %zu bytes): ", ciphertext_len); @@ -127,11 +127,11 @@ void encrypt_decrypt_aes_gcm(void) size_t len; ret = yaca_decrypt_init(&ctx, YACA_ENC_AES, YACA_BCM_GCM, key, iv); - if (ret < 0) + if (ret != 0) goto clean; ret = yaca_ctx_set_param(ctx, YACA_PARAM_GCM_AAD, aad, aad_len); - if (ret < 0) + if (ret != 0) goto clean; ret = yaca_get_output_length(ctx, ciphertext_len, &plaintext_len); @@ -148,17 +148,17 @@ void encrypt_decrypt_aes_gcm(void) goto clean; ret = yaca_decrypt_update(ctx, ciphertext, ciphertext_len, plaintext, &len); - if (ret < 0) + if (ret != 0) goto clean; plaintext_len = len; ret = yaca_ctx_set_param(ctx, YACA_PARAM_GCM_TAG, tag, tag_len); - if (ret < 0) + if (ret != 0) goto clean; ret = yaca_encrypt_final(ctx, plaintext + len, &len); - if (ret < 0) + if (ret != 0) goto clean; plaintext_len += len; @@ -184,7 +184,7 @@ int main() yaca_debug_set_error_cb(debug_func); int ret = yaca_init(); - if (ret < 0) + if (ret != 0) return ret; encrypt_decrypt_aes_gcm(); diff --git a/examples/key_exchange.c b/examples/key_exchange.c index 7d2bf78..90c0cd3 100644 --- a/examples/key_exchange.c +++ b/examples/key_exchange.c @@ -45,11 +45,11 @@ void key_exchange_dh(void) // generate private, public key ret = yaca_key_gen(&private_key, YACA_KEY_TYPE_DH_PRIV, YACA_KEY_2048BIT); - if (ret < 0) + if (ret != 0) goto clean; ret = yaca_key_extract_public(private_key, &public_key); - if (ret < 0) + if (ret != 0) goto clean; // get peer public key from file @@ -72,12 +72,12 @@ void key_exchange_dh(void) ret = yaca_key_import(&peer_key, YACA_KEY_TYPE_DH_PUB, NULL, buffer, size); - if (ret < 0) + if (ret != 0) goto clean; // derive secret ret = yaca_key_derive_dh(private_key, peer_key, &secret); - if (ret < 0) + if (ret != 0) goto clean; clean: @@ -105,11 +105,11 @@ void key_exchange_ecdh(void) // generate private, public key ret = yaca_key_gen(&private_key, YACA_KEY_TYPE_EC_PRIV, YACA_KEY_CURVE_P256); - if (ret < 0) + if (ret != 0) goto clean; ret = yaca_key_extract_public(private_key, &public_key); - if (ret < 0) + if (ret != 0) goto clean; // get peer public key from file @@ -131,12 +131,12 @@ void key_exchange_ecdh(void) goto clean; ret = yaca_key_import(&peer_key, YACA_KEY_TYPE_EC_PUB, NULL, buffer, size); - if (ret < 0) + if (ret != 0) goto clean; // derive secret ret = yaca_key_derive_dh(private_key, peer_key, &secret); - if (ret < 0) + if (ret != 0) goto clean; clean: @@ -154,7 +154,7 @@ int main() yaca_debug_set_error_cb(debug_func); int ret = yaca_init(); - if (ret < 0) + if (ret != 0) return ret; key_exchange_dh(); diff --git a/examples/seal.c b/examples/seal.c index 5d34da1..2f47074 100644 --- a/examples/seal.c +++ b/examples/seal.c @@ -143,7 +143,7 @@ int main() yaca_debug_set_error_cb(debug_func); int ret = yaca_init(); - if (ret < 0) + if (ret != 0) return ret; encrypt_seal(); diff --git a/examples/sign.c b/examples/sign.c index 1981b27..8555f8c 100644 --- a/examples/sign.c +++ b/examples/sign.c @@ -216,7 +216,7 @@ int main() yaca_debug_set_error_cb(debug_func); int ret = yaca_init(); - if (ret < 0) + if (ret != 0) return ret; // TODO simple? diff --git a/src/digest.c b/src/digest.c index 09fbd34..71f928a 100644 --- a/src/digest.c +++ b/src/digest.c @@ -131,7 +131,7 @@ API int yaca_digest_init(yaca_ctx_h *ctx, yaca_digest_algo_e algo) nc->ctx.get_output_length = get_digest_output_length; ret = digest_get_algorithm(algo, &md); - if (ret < 0) + if (ret != 0) goto free; nc->mdctx = EVP_MD_CTX_create(); diff --git a/src/encrypt.c b/src/encrypt.c index 86572e2..0237af9 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -429,7 +429,7 @@ API int yaca_get_iv_bits(yaca_enc_algo_e algo, int ret; ret = encrypt_get_algorithm(algo, bcm, key_bits, &cipher); - if (ret < 0) + if (ret != 0) return ret; ret = EVP_CIPHER_iv_length(cipher); diff --git a/src/key.c b/src/key.c index d8580a8..4c3b8a5 100644 --- a/src/key.c +++ b/src/key.c @@ -1111,7 +1111,7 @@ API int yaca_key_derive_pbkdf2(const char *password, return YACA_ERROR_TOO_BIG_ARGUMENT; ret = digest_get_algorithm(algo, &md); - if (ret < 0) + if (ret != 0) return ret; nk = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_byte_len); diff --git a/src/sign.c b/src/sign.c index 4e119be..d36155b 100644 --- a/src/sign.c +++ b/src/sign.c @@ -511,7 +511,7 @@ API int yaca_verify_init(yaca_ctx_h *ctx, } ret = digest_get_algorithm(algo, &md); - if (ret < 0) + if (ret != 0) goto free_ctx; nc->mdctx = EVP_MD_CTX_create(); diff --git a/src/simple.c b/src/simple.c index d82d4f2..e55aea1 100644 --- a/src/simple.c +++ b/src/simple.c @@ -46,11 +46,11 @@ API int yaca_digest_calc(yaca_digest_algo_e algo, return YACA_ERROR_INVALID_ARGUMENT; ret = yaca_digest_init(&ctx, algo); - if (ret < 0) + if (ret != 0) return ret; ret = yaca_digest_update(ctx, data, data_len); - if (ret < 0) + if (ret != 0) goto err; ret = yaca_get_digest_length(ctx, &ldigest_len); @@ -62,7 +62,7 @@ API int yaca_digest_calc(yaca_digest_algo_e algo, goto err; ret = yaca_digest_final(ctx, ldigest, &ldigest_len); - if (ret < 0) + if (ret != 0) goto err_free; yaca_ctx_free(ctx); -- 2.7.4 From 80e761d90050d81f5c33415b98c6f0fdd19671d3 Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Mon, 23 May 2016 10:02:33 +0200 Subject: [PATCH 05/16] Move HMAC to a separate function. Change-Id: I3f3aaa475d6617d9d1356433e0b0b4adaeaef388 --- src/sign.c | 266 +++++++++++++++++++++++++------------------------------------ 1 file changed, 109 insertions(+), 157 deletions(-) diff --git a/src/sign.c b/src/sign.c index d36155b..2a3aed3 100644 --- a/src/sign.c +++ b/src/sign.c @@ -25,6 +25,7 @@ #include #include +#include #include "internal.h" @@ -33,8 +34,7 @@ */ enum sign_op_type { OP_SIGN = 0, - OP_VERIFY_SYMMETRIC = 1, - OP_VERIFY_ASYMMETRIC = 2 + OP_VERIFY = 1 }; struct yaca_sign_ctx_s @@ -221,113 +221,128 @@ int get_sign_param(const yaca_ctx_h ctx, yaca_ex_param_e param, void **value, si return 0; } -static int create_sign_pkey(const yaca_key_h key, EVP_PKEY **pkey) +API int yaca_sign_init(yaca_ctx_h *ctx, + yaca_digest_algo_e algo, + const yaca_key_h key) { - const struct yaca_key_simple_s *simple_key = key_get_simple(key); + struct yaca_sign_ctx_s *nc = NULL; + const EVP_MD *md = NULL; + int ret; const struct yaca_key_evp_s *evp_key = key_get_evp(key); - if (pkey == NULL) + if (ctx == NULL || evp_key == NULL) return YACA_ERROR_INVALID_ARGUMENT; - if (simple_key != NULL) + switch (key->type) { - *pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, - NULL, - (unsigned char *)simple_key->d, - simple_key->bits / 8); - if (*pkey == NULL) { - ERROR_DUMP(YACA_ERROR_INTERNAL); - return YACA_ERROR_INTERNAL; - } + case YACA_KEY_TYPE_RSA_PRIV: + case YACA_KEY_TYPE_DSA_PRIV: + break; + case YACA_KEY_TYPE_EC_PRIV: + return YACA_ERROR_NOT_IMPLEMENTED; + default: + return YACA_ERROR_INVALID_ARGUMENT; + } - return 0; + nc = yaca_zalloc(sizeof(struct yaca_sign_ctx_s)); + if (nc == NULL) { + return YACA_ERROR_OUT_OF_MEMORY; } - if (evp_key != NULL) - { - *pkey = evp_key->evp; - /* Add a reference so we can free it afterwards anyway */ - CRYPTO_add(&(*pkey)->references, 1, CRYPTO_LOCK_EVP_PKEY); + nc->op_type = OP_SIGN; + nc->ctx.type = YACA_CTX_SIGN; + nc->ctx.ctx_destroy = destroy_sign_context; + nc->ctx.get_output_length = get_sign_output_length; + nc->ctx.set_param = set_sign_param; + nc->ctx.get_param = get_sign_param; - return 0; + ret = digest_get_algorithm(algo, &md); + if (ret != 0) + goto free_ctx; + + nc->mdctx = EVP_MD_CTX_create(); + if (nc->mdctx == NULL) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_ctx; } - return YACA_ERROR_INVALID_ARGUMENT; + ret = EVP_DigestSignInit(nc->mdctx, NULL, md, NULL, evp_key->evp); + if (ret != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_ctx; + } + + *ctx = (yaca_ctx_h)nc; + + return 0; + +free_ctx: + yaca_ctx_free((yaca_ctx_h)nc); + + return ret; } -/* TODO: error checking? - * should DES and IV keys be rejected by us or silently let them work? - */ -API int yaca_sign_init(yaca_ctx_h *ctx, - yaca_digest_algo_e algo, - const yaca_key_h key) +API int yaca_sign_hmac_init(yaca_ctx_h *ctx, + yaca_digest_algo_e algo, + const yaca_key_h key) { struct yaca_sign_ctx_s *nc = NULL; - EVP_PKEY *pkey; + EVP_PKEY *pkey = NULL; const EVP_MD *md; int ret; + const struct yaca_key_simple_s *simple_key = key_get_simple(key); - if (ctx == NULL) + if (ctx == NULL || simple_key == NULL || + (key->type != YACA_KEY_TYPE_SYMMETRIC && key->type != YACA_KEY_TYPE_DES)) return YACA_ERROR_INVALID_ARGUMENT; - ret = create_sign_pkey(key, &pkey); - if (ret != 0) - return ret; - nc = yaca_zalloc(sizeof(struct yaca_sign_ctx_s)); if (nc == NULL) { - ret = YACA_ERROR_OUT_OF_MEMORY; - goto free_key; + return YACA_ERROR_OUT_OF_MEMORY; } + nc->op_type = OP_SIGN; nc->ctx.type = YACA_CTX_SIGN; nc->ctx.ctx_destroy = destroy_sign_context; nc->ctx.get_output_length = get_sign_output_length; - nc->ctx.set_param = set_sign_param; - nc->ctx.get_param = get_sign_param; - switch (key->type) - { - case YACA_KEY_TYPE_SYMMETRIC: - case YACA_KEY_TYPE_RSA_PRIV: - case YACA_KEY_TYPE_DSA_PRIV: - nc->op_type = OP_SIGN; - break; - case YACA_KEY_TYPE_EC_PRIV: - ret = YACA_ERROR_NOT_IMPLEMENTED; - goto free_ctx; - default: - ret = YACA_ERROR_INVALID_ARGUMENT; + pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, + NULL, + (unsigned char *)simple_key->d, + simple_key->bits / 8); + if (pkey == NULL) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); goto free_ctx; } ret = digest_get_algorithm(algo, &md); if (ret != 0) - goto free_ctx; + goto free_pkey; nc->mdctx = EVP_MD_CTX_create(); if (nc->mdctx == NULL) { ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); - goto free_ctx; + goto free_pkey; } ret = EVP_DigestSignInit(nc->mdctx, NULL, md, NULL, pkey); if (ret != 1) { ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); - goto free_ctx; + goto free_pkey; } *ctx = (yaca_ctx_h)nc; + return 0; - ret = 0; - -free_ctx: - if (ret != 0) - yaca_ctx_free((yaca_ctx_h)nc); -free_key: +free_pkey: EVP_PKEY_free(pkey); +free_ctx: + yaca_ctx_free((yaca_ctx_h)nc); return ret; } @@ -341,16 +356,12 @@ API int yaca_sign_cmac_init(yaca_ctx_h *ctx, const EVP_CIPHER* cipher = NULL; EVP_PKEY *pkey = NULL; int ret; + const struct yaca_key_simple_s *simple_key = key_get_simple(key); - if (ctx == NULL || key == NULL || + if (ctx == NULL || simple_key == NULL || (key->type != YACA_KEY_TYPE_SYMMETRIC && key->type != YACA_KEY_TYPE_DES)) return YACA_ERROR_INVALID_ARGUMENT; - const struct yaca_key_simple_s *simple_key = key_get_simple(key); - - // the type is ok so we should be able to extract simple key - assert(simple_key != NULL); - nc = yaca_zalloc(sizeof(struct yaca_sign_ctx_s)); if (nc == NULL) { return YACA_ERROR_OUT_OF_MEMORY; @@ -470,46 +481,35 @@ API int yaca_verify_init(yaca_ctx_h *ctx, const yaca_key_h key) { struct yaca_sign_ctx_s *nc = NULL; - EVP_PKEY *pkey; - const EVP_MD *md; + const EVP_MD *md = NULL; int ret; + const struct yaca_key_evp_s *evp_key = key_get_evp(key); - if (ctx == NULL) + if (ctx == NULL || evp_key == NULL) return YACA_ERROR_INVALID_ARGUMENT; - ret = create_sign_pkey(key, &pkey); - if (ret != 0) - return ret; - - nc = yaca_zalloc(sizeof(struct yaca_sign_ctx_s)); - if (nc == NULL) { - ret = YACA_ERROR_OUT_OF_MEMORY; - goto free_key; - } - - nc->ctx.type = YACA_CTX_SIGN; - nc->ctx.ctx_destroy = destroy_sign_context; - nc->ctx.get_output_length = NULL; - nc->ctx.set_param = set_sign_param; - nc->ctx.get_param = get_sign_param; - switch (key->type) { - case YACA_KEY_TYPE_SYMMETRIC: - nc->op_type = OP_VERIFY_SYMMETRIC; - break; case YACA_KEY_TYPE_RSA_PUB: case YACA_KEY_TYPE_DSA_PUB: - nc->op_type = OP_VERIFY_ASYMMETRIC; break; case YACA_KEY_TYPE_EC_PUB: - ret = YACA_ERROR_NOT_IMPLEMENTED; - goto free_ctx; + return YACA_ERROR_NOT_IMPLEMENTED; default: - ret = YACA_ERROR_INVALID_ARGUMENT; - goto free_ctx; + return YACA_ERROR_INVALID_ARGUMENT; } + nc = yaca_zalloc(sizeof(struct yaca_sign_ctx_s)); + if (nc == NULL) + return YACA_ERROR_OUT_OF_MEMORY; + + nc->op_type = OP_VERIFY; + nc->ctx.type = YACA_CTX_SIGN; + nc->ctx.ctx_destroy = destroy_sign_context; + nc->ctx.get_output_length = NULL; + nc->ctx.set_param = set_sign_param; + nc->ctx.get_param = get_sign_param; + ret = digest_get_algorithm(algo, &md); if (ret != 0) goto free_ctx; @@ -521,19 +521,7 @@ API int yaca_verify_init(yaca_ctx_h *ctx, goto free_ctx; } - switch (nc->op_type) - { - case OP_VERIFY_SYMMETRIC: - ret = EVP_DigestSignInit(nc->mdctx, NULL, md, NULL, pkey); - break; - case OP_VERIFY_ASYMMETRIC: - ret = EVP_DigestVerifyInit(nc->mdctx, NULL, md, NULL, pkey); - break; - default: - ret = YACA_ERROR_INVALID_ARGUMENT; - goto free_ctx; - } - + ret = EVP_DigestVerifyInit(nc->mdctx, NULL, md, NULL, evp_key->evp); if (ret != 1) { ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); @@ -542,13 +530,10 @@ API int yaca_verify_init(yaca_ctx_h *ctx, *ctx = (yaca_ctx_h)nc; - ret = 0; + return 0; free_ctx: - if (ret != 0) - yaca_ctx_free((yaca_ctx_h)nc); -free_key: - EVP_PKEY_free(pkey); + yaca_ctx_free((yaca_ctx_h)nc); return ret; } @@ -560,21 +545,10 @@ API int yaca_verify_update(yaca_ctx_h ctx, struct yaca_sign_ctx_s *c = get_sign_ctx(ctx); int ret; - if (c == NULL || data == NULL || data_len == 0) + if (c == NULL || data == NULL || data_len == 0 || c->op_type != OP_VERIFY) return YACA_ERROR_INVALID_ARGUMENT; - switch (c->op_type) - { - case OP_VERIFY_SYMMETRIC: - ret = EVP_DigestSignUpdate(c->mdctx, data, data_len); - break; - case OP_VERIFY_ASYMMETRIC: - ret = EVP_DigestVerifyUpdate(c->mdctx, data, data_len); - break; - default: - return YACA_ERROR_INVALID_ARGUMENT; - } - + ret = EVP_DigestVerifyUpdate(c->mdctx, data, data_len); if (ret != 1) { ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); @@ -589,44 +563,22 @@ API int yaca_verify_final(yaca_ctx_h ctx, size_t signature_len) { struct yaca_sign_ctx_s *c = get_sign_ctx(ctx); - char mac_cmp[signature_len]; - size_t mac_cmp_len = signature_len; int ret; - if (c == NULL || signature == NULL || signature_len == 0) + if (c == NULL || signature == NULL || signature_len == 0 || c->op_type != OP_VERIFY) return YACA_ERROR_INVALID_ARGUMENT; - switch (c->op_type) - { - case OP_VERIFY_SYMMETRIC: - ret = EVP_DigestSignFinal(c->mdctx, - (unsigned char *)mac_cmp, - &mac_cmp_len); - if (ret != 1) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); - return ret; - } - - if (signature_len != mac_cmp_len || CRYPTO_memcmp(signature, mac_cmp, signature_len) != 0) - return YACA_ERROR_DATA_MISMATCH; - + ret = EVP_DigestVerifyFinal(c->mdctx, + (unsigned char *)signature, + signature_len); + if (ret == 1) return 0; - case OP_VERIFY_ASYMMETRIC: - ret = EVP_DigestVerifyFinal(c->mdctx, - (unsigned char *)signature, - signature_len); - if (ret == 1) - return 0; - - if (ret == 0) - ret = YACA_ERROR_DATA_MISMATCH; - else - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); - return ret; - default: - return YACA_ERROR_INVALID_ARGUMENT; - } + if (ret == 0) + ret = YACA_ERROR_DATA_MISMATCH; + else + ret = YACA_ERROR_INTERNAL; + + ERROR_DUMP(ret); + return ret; } -- 2.7.4 From b40ccdbcc5e7b475fa264ec7f4c9e9a8aab93285 Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Fri, 27 May 2016 08:55:01 +0200 Subject: [PATCH 06/16] Update openssl error handling. ERROR_DUMP always clears the error queue. ERROR_CLEAR clears the queue silently. One of them has to be called after an openssl error. ERROR_DUMP should be called for errors that we do not recognize. ERROR_CLEAR for other errors. Change-Id: I90844271378a87f4897f66c9664edf60bcb1e218 --- src/debug.c | 4 +++- src/internal.h | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/debug.c b/src/debug.c index 2bdaa74..4192585 100644 --- a/src/debug.c +++ b/src/debug.c @@ -42,8 +42,10 @@ API void yaca_debug_set_error_cb(yaca_error_cb fn) void error_dump(const char *file, int line, const char *function, int code) { - if (error_cb == NULL) + if (error_cb == NULL) { + ERR_clear_error(); return; + } static const size_t BUF_SIZE = 512; static const char ELLIPSIS[] = "...\n"; diff --git a/src/internal.h b/src/internal.h index 0aa764a..0e87776 100644 --- a/src/internal.h +++ b/src/internal.h @@ -26,6 +26,7 @@ #include #include +#include #include @@ -102,5 +103,6 @@ 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__, __func__, (code)) +#define ERROR_CLEAR() ERR_clear_error() #endif /* YACA_INTERNAL_H */ -- 2.7.4 From eb8cbe9d8e8c26600e79212a2ba611d8a2081458 Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Mon, 23 May 2016 10:11:51 +0200 Subject: [PATCH 07/16] Don't dump error in case of verification failure Change-Id: I65ea82e48c2bc6ba3fcfc4d63125c50dfa4b63b6 --- src/sign.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/sign.c b/src/sign.c index 2a3aed3..33a2850 100644 --- a/src/sign.c +++ b/src/sign.c @@ -571,14 +571,16 @@ API int yaca_verify_final(yaca_ctx_h ctx, ret = EVP_DigestVerifyFinal(c->mdctx, (unsigned char *)signature, signature_len); + if (ret == 1) return 0; - if (ret == 0) - ret = YACA_ERROR_DATA_MISMATCH; - else - ret = YACA_ERROR_INTERNAL; + if (ret == 0) { + ERROR_CLEAR(); + return YACA_ERROR_DATA_MISMATCH; + } + ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); return ret; } -- 2.7.4 From 058473ba8f150f7f298616456c0dd6696f2cea3f Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Wed, 18 May 2016 12:19:48 +0200 Subject: [PATCH 08/16] Use new HMAC API in example Change-Id: I4479c5ff16deda4741dd3164c49e3bd2a5ba5551 --- examples/sign.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/examples/sign.c b/examples/sign.c index 8555f8c..e9268bb 100644 --- a/examples/sign.c +++ b/examples/sign.c @@ -98,7 +98,8 @@ finish: void sign_verify_hmac(void) { - char* signature = NULL; + char *signature1 = NULL; + char *signature2 = NULL; size_t signature_len; yaca_ctx_h ctx = YACA_CTX_NULL; @@ -109,7 +110,7 @@ void sign_verify_hmac(void) return; // SIGN - if (yaca_sign_init(&ctx, YACA_DIGEST_SHA512, key) != 0) + if (yaca_sign_hmac_init(&ctx, YACA_DIGEST_SHA512, key) != 0) goto finish; if (yaca_sign_update(ctx, lorem4096, LOREM4096_SIZE) != 0) @@ -118,32 +119,42 @@ void sign_verify_hmac(void) if (yaca_get_sign_length(ctx, &signature_len) != 0) goto finish; - if ((signature = yaca_malloc(signature_len)) == NULL) + if ((signature1 = yaca_malloc(signature_len)) == NULL) goto finish; - if (yaca_sign_final(ctx, signature, &signature_len) != 0) + if (yaca_sign_final(ctx, signature1, &signature_len) != 0) goto finish; - dump_hex(signature, signature_len, "HMAC Signature of lorem4096:"); + dump_hex(signature1, signature_len, "HMAC Signature of lorem4096:"); // CLEANUP yaca_ctx_free(ctx); ctx = YACA_CTX_NULL; // VERIFY - if (yaca_verify_init(&ctx, YACA_DIGEST_SHA512, key) != 0) + if (yaca_sign_hmac_init(&ctx, YACA_DIGEST_SHA512, key) != 0) goto finish; - if (yaca_verify_update(ctx, lorem4096, LOREM4096_SIZE) != 0) + if (yaca_sign_update(ctx, lorem4096, LOREM4096_SIZE) != 0) goto finish; - if (yaca_verify_final(ctx, signature, signature_len) != 0) + if (yaca_get_sign_length(ctx, &signature_len) != 0) + goto finish; + + if ((signature2 = yaca_malloc(signature_len)) == NULL) + goto finish; + + if (yaca_sign_final(ctx, signature2, &signature_len) != 0) + goto finish; + + if (yaca_memcmp(signature1, signature2, signature_len) != 0) printf("HMAC verification failed\n"); else printf("HMAC verification succesful\n"); finish: - yaca_free(signature); + yaca_free(signature1); + yaca_free(signature2); yaca_key_free(key); yaca_ctx_free(ctx); } -- 2.7.4 From dd33d62e79a4085138c2bf22ea0d6c32707a0215 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Wed, 25 May 2016 15:48:23 +0200 Subject: [PATCH 09/16] Cleanup boilerplate notices. Change-Id: I162fe9cdfa095a4aefe0d14e83b55fd2a786c4d3 --- examples/misc.c | 23 +++++++++++++++++++++++ examples/sign.c | 2 +- src/crypto.c | 5 +++++ src/debug.c | 11 +++++++---- src/digest.c | 5 +++++ src/encrypt.c | 5 +++++ src/internal.h | 4 ++-- src/key.c | 5 +++++ src/seal.c | 5 +++++ src/sign.c | 5 +++++ src/simple.c | 5 +++++ 11 files changed, 68 insertions(+), 7 deletions(-) diff --git a/examples/misc.c b/examples/misc.c index ef8c53c..2a96106 100644 --- a/examples/misc.c +++ b/examples/misc.c @@ -1,3 +1,26 @@ +/* + * 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 misc.c + * @brief + */ + #include #include #include diff --git a/examples/sign.c b/examples/sign.c index e9268bb..c66e5d7 100644 --- a/examples/sign.c +++ b/examples/sign.c @@ -1,7 +1,7 @@ /* * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved * - * Contact: + * 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. diff --git a/src/crypto.c b/src/crypto.c index bca42a8..ec1d35b 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -16,6 +16,11 @@ * limitations under the License */ +/** + * @file crypto.c + * @brief + */ + #include #include diff --git a/src/debug.c b/src/debug.c index 4192585..b5f55bb 100644 --- a/src/debug.c +++ b/src/debug.c @@ -1,5 +1,7 @@ /* - * Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved + * 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. @@ -13,9 +15,10 @@ * See the License for the specific language governing permissions and * limitations under the License */ -/* - * @file debug.c - * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + +/** + * @file debug.c + * @brief */ #include diff --git a/src/digest.c b/src/digest.c index 71f928a..89eb1ff 100644 --- a/src/digest.c +++ b/src/digest.c @@ -16,6 +16,11 @@ * limitations under the License */ +/** + * @file digest.c + * @brief + */ + #include #include diff --git a/src/encrypt.c b/src/encrypt.c index 0237af9..b28c6be 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -16,6 +16,11 @@ * limitations under the License */ +/** + * @file encrypt.c + * @brief + */ + #include #include #include diff --git a/src/internal.h b/src/internal.h index 0e87776..9a2a102 100644 --- a/src/internal.h +++ b/src/internal.h @@ -17,8 +17,8 @@ */ /** - * @file encrypt.h - * @brief Internal API + * @file internal.h + * @brief */ #ifndef YACA_INTERNAL_H diff --git a/src/key.c b/src/key.c index 4c3b8a5..e3d5ffc 100644 --- a/src/key.c +++ b/src/key.c @@ -16,6 +16,11 @@ * limitations under the License */ +/** + * @file key.c + * @brief + */ + #include #include #include diff --git a/src/seal.c b/src/seal.c index bbaa2ca..cbfe0ca 100644 --- a/src/seal.c +++ b/src/seal.c @@ -16,6 +16,11 @@ * limitations under the License */ +/** + * @file seal.c + * @brief + */ + #include #include #include diff --git a/src/sign.c b/src/sign.c index 33a2850..1a3a589 100644 --- a/src/sign.c +++ b/src/sign.c @@ -16,6 +16,11 @@ * limitations under the License */ +/** + * @file sign.c + * @brief + */ + #include #include diff --git a/src/simple.c b/src/simple.c index e55aea1..80414f8 100644 --- a/src/simple.c +++ b/src/simple.c @@ -16,6 +16,11 @@ * limitations under the License */ +/** + * @file simple.c + * @brief + */ + #include #include #include -- 2.7.4 From e80751b57c80355ace78a55d3327e4b948bb9822 Mon Sep 17 00:00:00 2001 From: sangsu Date: Wed, 25 May 2016 11:36:27 +0900 Subject: [PATCH 10/16] add @since_tizen 3.0 in yaca api header files Change-Id: I77736606ae86c6180e4eb0221610e03cc9abb9e5 Signed-off-by: sangsu --- api/yaca/crypto.h | 32 ++++++++++++++++++++++++ api/yaca/digest.h | 6 +++++ api/yaca/encrypt.h | 18 ++++++++++++-- api/yaca/error.h | 26 +++++++++++++------- api/yaca/key.h | 70 ++++++++++++++++++++++++++++++++--------------------- api/yaca/seal.h | 12 +++++++++ api/yaca/sign.h | 28 ++++++++++++++++----- api/yaca/simple.h | 22 ++++++++++++++--- api/yaca/types.h | 22 +++++++++++++++++ packaging/yaca.spec | 1 + src/CMakeLists.txt | 2 +- src/key.c | 0 12 files changed, 190 insertions(+), 49 deletions(-) mode change 100644 => 100755 api/yaca/error.h mode change 100644 => 100755 api/yaca/key.h mode change 100644 => 100755 src/key.c diff --git a/api/yaca/crypto.h b/api/yaca/crypto.h index 76a2897..5a44a9d 100644 --- a/api/yaca/crypto.h +++ b/api/yaca/crypto.h @@ -41,12 +41,16 @@ extern "C" { /** * @brief NULL value for the crypto context. + * + * @since_tizen 3.0 */ #define YACA_CTX_NULL ((yaca_ctx_h) NULL) /** * @brief Initializes the library. Must be called before any other crypto function. * + * @since_tizen 3.0 + * * @return 0 on success, negative on error. * @see yaca_exit() */ @@ -55,6 +59,8 @@ int yaca_init(void); /** * @brief Closes the library. Must be called before exiting the application. * + * @since_tizen 3.0 + * * @see yaca_init() */ void yaca_exit(void); @@ -62,6 +68,8 @@ void yaca_exit(void); /** * @brief Allocates the memory. * + * @since_tizen 3.0 + * * @param[in] size Size of the allocation (bytes). * * @return NULL on failure, pointer to allocated memory otherwise. @@ -72,6 +80,8 @@ void *yaca_malloc(size_t size); /** * @brief Allocates the zeroed memory. * + * @since_tizen 3.0 + * * @param[in] size Size of the allocation (bytes). * * @return NULL on failure, pointer to allocated and zeroed memory otherwise. @@ -82,6 +92,8 @@ void *yaca_zalloc(size_t size); /** * @brief Re-allocates the memory. * + * @since_tizen 3.0 + * * @param[in] addr Address of the memory to be reallocated. * @param[in] size Size of the new allocation (bytes). * @@ -94,6 +106,8 @@ void *yaca_realloc(void *addr, size_t size); * @brief Frees the memory allocated by yaca_malloc(), yaca_zalloc(), * yaca_realloc() or one of the cryptographic operations. * + * @since_tizen 3.0 + * * @param[in] ptr Pointer to the memory to be freed. * @see yaca_malloc(), yaca_zalloc(), yaca_realloc() * @@ -103,6 +117,8 @@ void yaca_free(void *ptr); /** * @brief Generates random data. * + * @since_tizen 3.0 + * * @param[in,out] data Pointer to the memory to be randomized. * @param[in] data_len Length of the memory to be randomized. * @@ -114,6 +130,8 @@ int yaca_rand_bytes(char *data, size_t data_len); * @brief Sets the extended context parameters. Can only be called on an * initialized context. * + * @since_tizen 3.0 + * * @param[in,out] ctx Previously initialized crypto context. * @param[in] param Parameter to be set. * @param[in] value Parameter value. @@ -131,6 +149,8 @@ int yaca_ctx_set_param(yaca_ctx_h ctx, * @brief Returns the extended context parameters. Can only be called on an * initialized context. * + * @since_tizen 3.0 + * * @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 yaca_free()). @@ -148,6 +168,8 @@ int yaca_ctx_get_param(const yaca_ctx_h ctx, * @brief Destroys the crypto context. Must be called on all contexts that are * no longer used. Passing YACA_CTX_NULL is allowed. * + * @since_tizen 3.0 + * * @param[in,out] ctx Crypto context. * @see #yaca_ctx_h * @@ -158,6 +180,8 @@ void yaca_ctx_free(yaca_ctx_h ctx); * @brief Returns the output length for a given algorithm. Can only be called * on an initialized context. * + * @since_tizen 3.0 + * * @param[in] ctx Previously initialized crypto context. * @param[in] input_len Length of the input data to be processed. * @param[in] output_len Required length of the output. @@ -168,22 +192,30 @@ int yaca_get_output_length(const yaca_ctx_h ctx, size_t input_len, size_t *outpu /** * @brief Wrapper - returns the length of the digest (for a given context). + * + * @since_tizen 3.0 */ #define yaca_get_digest_length(ctxa, output_len) yaca_get_output_length((ctxa), 0, (output_len)) /** * @brief Wrapper - returns the length of the signature (for a given context). + * + * @since_tizen 3.0 */ #define yaca_get_sign_length(ctxa, output_len) yaca_get_output_length((ctxa), 0, (output_len)) /** * @brief Wrapper - returns the length of the block (for a given context). + * + * @since_tizen 3.0 */ #define yaca_get_block_length(ctxa, output_len) yaca_get_output_length((ctxa), 0, (output_len)) /** * @brief Safely compares first @b len bytes of two buffers. * + * @since_tizen 3.0 + * * @param[in] first Pointer to the first buffer. * @param[in] second Pointer to the second buffer. * @param[in] len Length to compare. diff --git a/api/yaca/digest.h b/api/yaca/digest.h index 5e3aa0d..1938360 100644 --- a/api/yaca/digest.h +++ b/api/yaca/digest.h @@ -42,6 +42,8 @@ extern "C" { /** * @brief Initializes a digest context. * + * @since_tizen 3.0 + * * @param[out] ctx Newly created context (must be freed with yaca_ctx_free()). * @param[in] algo Digest algorithm that will be used. * @@ -53,6 +55,8 @@ int yaca_digest_init(yaca_ctx_h *ctx, yaca_digest_algo_e algo); /** * @brief Feeds the data into the message digest algorithm. * + * @since_tizen 3.0 + * * @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. @@ -65,6 +69,8 @@ int yaca_digest_update(yaca_ctx_h ctx, const char *data, size_t data_len); /** * @brief Calculates the final digest. * + * @since_tizen 3.0 + * * @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()). diff --git a/api/yaca/encrypt.h b/api/yaca/encrypt.h index 7e81d9b..cc07262 100644 --- a/api/yaca/encrypt.h +++ b/api/yaca/encrypt.h @@ -44,6 +44,8 @@ extern "C" { /** * @brief Initializes an encryption context. * + * @since_tizen 3.0 + * * @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. @@ -62,6 +64,8 @@ int yaca_encrypt_init(yaca_ctx_h *ctx, /** * @brief Encrypts chunk of the data. * + * @since_tizen 3.0 + * * @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. @@ -81,6 +85,8 @@ int yaca_encrypt_update(yaca_ctx_h ctx, /** * @brief Encrypts the final chunk of the data. * + * @since_tizen 3.0 + * * @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()). @@ -96,6 +102,8 @@ int yaca_encrypt_final(yaca_ctx_h ctx, /** * @brief Initializes an decryption context. * + * @since_tizen 3.0 + * * @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. @@ -114,6 +122,8 @@ int yaca_decrypt_init(yaca_ctx_h *ctx, /** * @brief Decrypts chunk of the data. * + * @since_tizen 3.0 + * * @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. @@ -133,6 +143,8 @@ int yaca_decrypt_update(yaca_ctx_h ctx, /** * @brief Decrypts the final chunk of the data. * + * @since_tizen 3.0 + * * @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()). @@ -148,8 +160,10 @@ int yaca_decrypt_final(yaca_ctx_h ctx, /** * @brief Returns the recomended/default length of the IV for a given encryption configuration. * - * If returned iv_bits equals 0 that means that for this - * specific algorithm and its parameters IV is not used. + * @since_tizen 3.0 + * + * @remarks If returned iv_bits equals 0 that means that for this + * specific algorithm and its parameters IV is not used. * * @param[in] algo Encryption algorithm. * @param[in] bcm Chain mode. diff --git a/api/yaca/error.h b/api/yaca/error.h old mode 100644 new mode 100755 index 8aa150b..26f1979 --- a/api/yaca/error.h +++ b/api/yaca/error.h @@ -24,10 +24,15 @@ #ifndef YACA_ERROR_H #define YACA_ERROR_H +#include + #ifdef __cplusplus extern "C" { #endif + +#define TIZEN_ERROR_YACA -0x01E30000 + /** * @defgroup Error Yet another Crypto API - error enums. * @@ -35,17 +40,20 @@ extern "C" { */ /** - * @brief Error enums + * @brief Error enums + * + * @since_tizen 3.0 */ enum __yaca_error_code { - YACA_ERROR_NONE = 0, - YACA_ERROR_INVALID_ARGUMENT = -1, - YACA_ERROR_NOT_IMPLEMENTED = -2, - YACA_ERROR_INTERNAL = -3, - YACA_ERROR_TOO_BIG_ARGUMENT = -4, - YACA_ERROR_OUT_OF_MEMORY = -5, - YACA_ERROR_DATA_MISMATCH = -6, - YACA_ERROR_PASSWORD_INVALID = -7 + YACA_ERROR_NONE = TIZEN_ERROR_NONE, + YACA_ERROR_INVALID_ARGUMENT = TIZEN_ERROR_INVALID_PARAMETER, + + YACA_ERROR_NOT_IMPLEMENTED = TIZEN_ERROR_YACA | 0x01, + YACA_ERROR_INTERNAL = TIZEN_ERROR_YACA | 0x02, + YACA_ERROR_TOO_BIG_ARGUMENT = TIZEN_ERROR_YACA | 0x03, + YACA_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_YACA | 0x04, + YACA_ERROR_DATA_MISMATCH = TIZEN_ERROR_YACA | 0x05, + YACA_ERROR_PASSWORD_INVALID = TIZEN_ERROR_YACA | 0x06 }; /**@}*/ diff --git a/api/yaca/key.h b/api/yaca/key.h old mode 100644 new mode 100755 index e020171..e03834d --- a/api/yaca/key.h +++ b/api/yaca/key.h @@ -46,6 +46,8 @@ extern "C" { /** * @brief Get key's type. * + * @since_tizen 3.0 + * * @param[in] key Key which type we return. * @param[out] key_type Key type. * @@ -56,6 +58,8 @@ int yaca_key_get_type(const yaca_key_h key, yaca_key_type_e *key_type); /** * @brief Get key's length (in bits). * + * @since_tizen 3.0 + * * @param[in] key Key which length we return. * @param[out] key_bits Key length in bits. * @@ -66,21 +70,23 @@ int yaca_key_get_bits(const yaca_key_h key, size_t *key_bits); /** * @brief Imports a key. * - * This function imports a key trying to match it to the key_type specified. - * It should autodetect both, key format and file format. + * @since_tizen 3.0 * - * 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. + * @remarks This function imports a key trying to match it to the key_type specified. + * It should autodetect both, key format and file format. * - * 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. + * 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. * - * If the key is encrypted the algorithm will be autodetected and password - * used. If it's not known if the key is encrypted one should pass NULL as - * password and check for the YACA_ERROR_PASSWORD_INVALID return code. + * 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. + * + * If the key is encrypted the algorithm will be autodetected and password + * used. If it's not known if the key is encrypted one should pass NULL as + * password and check for the YACA_ERROR_PASSWORD_INVALID return code. * * @param[out] key Returned key (must be freed with yaca_key_free()). * @param[in] key_type Type of the key. @@ -101,24 +107,26 @@ int yaca_key_import(yaca_key_h *key, /** * @brief 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. + * @since_tizen 3.0 + * + * @remarks 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. + * 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 + * 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 * - * If no password is provided the exported key will be unencrypted. Only private - * RSA/DSA exported as PEM can be encrypted. + * If no password is provided the exported key will be unencrypted. Only private + * RSA/DSA exported as PEM can be encrypted. * - * TODO: document the default encryption algorithm (AES256 for FORMAT_DEFAULT, - * unknown yet for the FORMAT_PKCS8) + * TODO:document the default encryption algorithm (AES256 for FORMAT_DEFAULT, + * unknown yet for the FORMAT_PKCS8). * * @param[in] key Key to be exported. * @param[in] key_fmt Format of the key. @@ -141,7 +149,9 @@ int yaca_key_export(const yaca_key_h key, /** * @brief Generates a secure key (or an initialization vector). * - * This function is used to generate symmetric and private asymmetric keys. + * @since_tizen 3.0 + * + * @remarks This function is used to generate symmetric and private asymmetric keys. * * @param[out] key Newly generated key (must be freed with yaca_key_free()). * @param[in] key_type Type of the key to be generated. @@ -157,6 +167,8 @@ int yaca_key_gen(yaca_key_h *key, /** * @brief Extracts public key from a private one. * + * @since_tizen 3.0 + * * @param[in] prv_key Private key to extract the public one from. * @param[out] pub_key Extracted public key (must be freed with yaca_key_free()). * @@ -168,6 +180,8 @@ int yaca_key_extract_public(const yaca_key_h prv_key, yaca_key_h *pub_key); /** * @brief Frees the key created by the library. Passing YACA_KEY_NULL is allowed. * + * @since_tizen 3.0 + * * @param key Key to be freed. * @see yaca_key_import(), yaca_key_export(), yaca_key_gen() * @@ -221,6 +235,8 @@ int yaca_key_derive_kea(const yaca_key_h prv_key, /** * @brief Derives a key from user password (PKCS #5 a.k.a. pbkdf2 algorithm). * + * @since_tizen 3.0 + * * @param[in] password User password as a NULL-terminated string. * @param[in] salt Salt, should be non-zero. * @param[in] salt_len Length of the salt. diff --git a/api/yaca/seal.h b/api/yaca/seal.h index 4f7b2fa..bbf4ee7 100644 --- a/api/yaca/seal.h +++ b/api/yaca/seal.h @@ -46,6 +46,8 @@ extern "C" { /** * @brief Initializes an asymmetric encryption context. * + * @since_tizen 3.0 + * * @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. @@ -68,6 +70,8 @@ int yaca_seal_init(yaca_ctx_h *ctx, /** * @brief Encrypts piece of the data. * + * @since_tizen 3.0 + * * @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. @@ -87,6 +91,8 @@ int yaca_seal_update(yaca_ctx_h ctx, /** * @brief Encrypts the final piece of the data. * + * @since_tizen 3.0 + * * @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()). @@ -102,6 +108,8 @@ int yaca_seal_final(yaca_ctx_h ctx, /** * @brief Initializes an asymmetric decryption context. * + * @since_tizen 3.0 + * * @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. @@ -124,6 +132,8 @@ int yaca_open_init(yaca_ctx_h *ctx, /** * @brief Decrypts piece of the data. * + * @since_tizen 3.0 + * * @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. @@ -143,6 +153,8 @@ int yaca_open_update(yaca_ctx_h ctx, /** * @brief Decrypts last chunk of sealed message. * + * @since_tizen 3.0 + * * @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()). diff --git a/api/yaca/sign.h b/api/yaca/sign.h index beb5df2..36ba4dc 100644 --- a/api/yaca/sign.h +++ b/api/yaca/sign.h @@ -43,8 +43,10 @@ extern "C" { /** * @brief Initializes a signature context for asymmetric signatures. * - * For verification use yaca_verify_init(), yaca_verify_update() and - * yaca_verify_final() functions with matching public key. + * @since_tizen 3.0 + * + * @remarks For verification use yaca_verify_init(), yaca_verify_update() and + * yaca_verify_final() functions with matching public key. * * @param[out] ctx Newly created context (must be freed with yaca_ctx_free()). * @param[in] algo Digest algorithm that will be used. @@ -66,8 +68,10 @@ int yaca_sign_init(yaca_ctx_h *ctx, /** * @brief Initializes a signature context for HMAC. * - * For verification, calculate message HMAC and compare with received MAC using - * yaca_memcmp(). + * @since_tizen 3.0 + * + * @remarks For verification, calculate message HMAC and compare with received MAC using + * yaca_memcmp(). * * @param[out] ctx Newly created context (must be freed with yaca_ctx_free()). * @param[in] algo Digest algorithm that will be used. @@ -86,8 +90,10 @@ int yaca_sign_hmac_init(yaca_ctx_h *ctx, /** * @brief Initializes a signature context for CMAC. * - * For verification, calculate message CMAC and compare with received MAC using - * yaca_memcmp(). + * @since_tizen 3.0 + * + * @remarks For verification, calculate message CMAC and compare with received MAC using + * yaca_memcmp(). * * @param[out] ctx Newly created context (must be freed with yaca_ctx_free()). * @param[in] algo Encryption algorithm that will be used. @@ -106,6 +112,8 @@ int yaca_sign_cmac_init(yaca_ctx_h *ctx, /** * @brief Feeds the data into the digital signature or MAC algorithm. * + * @since_tizen 3.0 + * * @param[in,out] ctx Context created by yaca_sign_init(), * yaca_sign_hmac_init() or yaca_sign_cmac_init(). * @param[in] data Data to be signed. @@ -122,6 +130,8 @@ int yaca_sign_update(yaca_ctx_h ctx, /** * @brief Calculates the final signature or MAC. * + * @since_tizen 3.0 + * * @param[in,out] ctx A valid sign context. * @param[out] signature Buffer for the MAC or the signature, * (must be allocated by client, see yaca_get_sign_length()). @@ -139,6 +149,8 @@ int yaca_sign_final(yaca_ctx_h ctx, /** * @brief Initializes a signature verification context for asymmetric signatures * + * @since_tizen 3.0 + * * @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 Public key that will be used. Algorithm is deduced based on @@ -158,6 +170,8 @@ int yaca_verify_init(yaca_ctx_h *ctx, /** * @brief Feeds the data into the digital signature verification algorithm. * + * @since_tizen 3.0 + * * @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. @@ -172,6 +186,8 @@ int yaca_verify_update(yaca_ctx_h ctx, /** * @brief Performs the verification. * + * @since_tizen 3.0 + * * @param[in,out] ctx A valid verify context. * @param[in] signature Input signature (returned by yaca_sign_final()). * @param[in] signature_len Size of the signature. diff --git a/api/yaca/simple.h b/api/yaca/simple.h index c1d1d2b..b43a60b 100644 --- a/api/yaca/simple.h +++ b/api/yaca/simple.h @@ -50,6 +50,8 @@ extern "C" { /** * @brief Calculate a digest of a buffer. * + * @since_tizen 3.0 + * * @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. @@ -69,6 +71,8 @@ int yaca_digest_calc(yaca_digest_algo_e algo, /** * @brief Encrypt data using a symmetric cipher. * + * @since_tizen 3.0 + * * @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). @@ -94,6 +98,8 @@ int yaca_encrypt(yaca_enc_algo_e algo, /** * @brief Decrypt data using a symmetric cipher. * + * @since_tizen 3.0 + * * @param[in] algo Decryption algorithm that was used to encrypt the data. * @param[in] bcm Chaining mode that was used to encrypt the data. * @param[in] sym_key Symmetric encryption key that was used to encrypt the data. @@ -119,6 +125,8 @@ int yaca_decrypt(yaca_enc_algo_e algo, /** * @brief Create a signature using asymmetric private key. * + * @since_tizen 3.0 + * * @param[in] algo Digest algorithm that will be used. * @param[in] key Private key that will be used. Algorithm is * deduced based on key type. Supported key types: @@ -144,6 +152,8 @@ int yaca_sign(yaca_digest_algo_e algo, /** * @brief Verify a signature using asymmetric public key. * + * @since_tizen 3.0 + * * @param[in] algo Digest algorithm that will be used. * @param[in] key Public key that will be used. Algorithm is * deduced based on key type. Supported key types: @@ -169,8 +179,10 @@ int yaca_verify(yaca_digest_algo_e algo, /** * @brief Calculate a HMAC of given message using symmetric key. * - * For verification, calculate message HMAC and compare with received MAC using - * yaca_memcmp(). + * @since_tizen 3.0 + * + * @remarks For verification, calculate message HMAC and compare with received MAC using + * yaca_memcmp(). * * @param[in] algo Digest algorithm that will be used. * @param[in] key Key that will be used. Supported key types: @@ -195,8 +207,10 @@ int yaca_hmac(yaca_digest_algo_e algo, /** * @brief Calculate a CMAC of given message using symmetric key. * - * For verification, calculate message CMAC and compare with received MAC using - * yaca_memcmp(). + * @since_tizen 3.0 + * + * @remarks For verification, calculate message CMAC and compare with received MAC using + * yaca_memcmp(). * * @param[in] algo Encryption algorithm that will be used. * @param[in] key Key that will be used. Supported key types: diff --git a/api/yaca/types.h b/api/yaca/types.h index 5a99113..7ba8cd7 100644 --- a/api/yaca/types.h +++ b/api/yaca/types.h @@ -38,16 +38,22 @@ extern "C" { /** * @brief Context + * + * @since_tizen 3.0 */ typedef struct yaca_ctx_s *yaca_ctx_h; /** * @brief Key + * + * @since_tizen 3.0 */ typedef struct yaca_key_s *yaca_key_h; /** * @brief Key formats + * + * @since_tizen 3.0 */ typedef enum { YACA_KEY_FORMAT_DEFAULT, /**< key is either PKCS#1 for RSA or SSLeay for DSA, also use this option for symmetric */ @@ -56,6 +62,8 @@ typedef enum { /** * @brief Key file formats + * + * @since_tizen 3.0 */ typedef enum { YACA_KEY_FILE_FORMAT_RAW, /**< key file is in raw binary format, used for symmetric keys */ @@ -66,6 +74,8 @@ typedef enum { /** * @brief Key types, IV is considered as key + * + * @since_tizen 3.0 */ typedef enum { YACA_KEY_TYPE_SYMMETRIC, /**< Generic symmetric cipher KEY */ @@ -88,6 +98,8 @@ typedef enum { /** * @brief Key length, It is possible to use arbitrary integer instead, this enums are placed here to avoid magic numbers. + * + * @since_tizen 3.0 */ typedef enum { YACA_KEY_IV_UNSAFE_24BIT = 24, /**< 24-bit IV */ @@ -113,6 +125,8 @@ typedef enum { /** * @brief Message digest algorithms. + * + * @since_tizen 3.0 */ typedef enum { YACA_DIGEST_MD5, /**< Message digest algorithm MD5 */ @@ -125,6 +139,8 @@ typedef enum { /** * @brief Symmetric encryption algorithms + * + * @since_tizen 3.0 */ typedef enum { /** @@ -230,6 +246,8 @@ typedef enum { /** * @brief Chaining modes for block ciphers + * + * @since_tizen 3.0 */ typedef enum { /** @@ -302,6 +320,8 @@ typedef enum { /** * @brief Non-standard parameters for algorithms + * + * @since_tizen 3.0 */ typedef enum { YACA_PARAM_PADDING, /**< Padding */ @@ -317,6 +337,8 @@ typedef enum { /** * @brief Paddings supported by Yet Another Crypto API + * + * @since_tizen 3.0 */ typedef enum { YACA_PADDING_NONE = 0, /**< total number of data MUST multiple of block size, Default */ diff --git a/packaging/yaca.spec b/packaging/yaca.spec index 126018c..327df37 100644 --- a/packaging/yaca.spec +++ b/packaging/yaca.spec @@ -6,6 +6,7 @@ License: Apache-2.0 Group: Security/Other Summary: Yet Another Crypto API BuildRequires: cmake +BuildRequires: pkgconfig(capi-base-common) BuildRequires: pkgconfig(openssl) Requires(post): /sbin/ldconfig Requires(postun): /sbin/ldconfig diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9d8369b..e21ca95 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -45,7 +45,7 @@ SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${_LIB_VERSION_}) ## Link libraries ############################################################## -PKG_CHECK_MODULES(YACA_DEPS REQUIRED openssl) +PKG_CHECK_MODULES(YACA_DEPS REQUIRED openssl capi-base-common) INCLUDE_DIRECTORIES(${API_FOLDER}) INCLUDE_DIRECTORIES(SYSTEM ${YACA_DEPS_INCLUDE_DIRS}) diff --git a/src/key.c b/src/key.c old mode 100644 new mode 100755 -- 2.7.4 From 927c99596f36de494d4ed4e54cdda81e699b478d Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Wed, 18 May 2016 15:35:39 +0200 Subject: [PATCH 11/16] Simple API for signatures - implementation Change-Id: I0beab0dd414d2c12e08a262b5c2750acbc711763 --- src/simple.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/src/simple.c b/src/simple.c index 80414f8..3db1098 100644 --- a/src/simple.c +++ b/src/simple.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "internal.h" @@ -236,3 +237,121 @@ err: yaca_ctx_free(ctx); return ret; } + +static int sign(const yaca_ctx_h ctx, const char *data, size_t data_len, + char** signature, size_t* signature_len) +{ + int ret; + + assert(signature != NULL); + assert(signature_len != NULL); + + ret = yaca_sign_update(ctx, data, data_len); + if (ret != 0) + return ret; + + ret = yaca_get_sign_length(ctx, signature_len); + if (ret != 0) + return ret; + + *signature = yaca_malloc(*signature_len); + if (signature == NULL) + return YACA_ERROR_OUT_OF_MEMORY; + + ret = yaca_sign_final(ctx, *signature, signature_len); + if (ret != 0) { + yaca_free(*signature); + *signature = NULL; + } + + return ret; +} + +API int yaca_sign(yaca_digest_algo_e algo, + const yaca_key_h key, + const char *data, + size_t data_len, + char** signature, + size_t* signature_len) +{ + int ret; + yaca_ctx_h ctx = YACA_CTX_NULL; + + ret = yaca_sign_init(&ctx, algo, key); + if (ret != 0) + return ret; + + ret = sign(ctx, data, data_len, signature, signature_len); + + yaca_ctx_free(ctx); + + return ret; +} + +API int yaca_verify(yaca_digest_algo_e algo, + const yaca_key_h key, + const char *data, + size_t data_len, + const char* signature, + size_t signature_len) +{ + int ret; + yaca_ctx_h ctx = YACA_CTX_NULL; + + ret = yaca_verify_init(&ctx, algo, key); + if (ret != 0) + return ret; + + ret = yaca_verify_update(ctx, data, data_len); + if (ret != 0) + goto free_ctx; + + ret = yaca_verify_final(ctx, signature, signature_len); + +free_ctx: + yaca_ctx_free(ctx); + + return ret; +} + +API int yaca_hmac(yaca_digest_algo_e algo, + const yaca_key_h key, + const char *data, + size_t data_len, + char** mac, + size_t* mac_len) +{ + int ret; + yaca_ctx_h ctx = YACA_CTX_NULL; + + ret = yaca_sign_hmac_init(&ctx, algo, key); + if (ret != 0) + return ret; + + ret = sign(ctx, data, data_len, mac, mac_len); + + yaca_ctx_free(ctx); + + return ret; +} + +API int yaca_cmac(yaca_enc_algo_e algo, + const yaca_key_h key, + const char *data, + size_t data_len, + char** mac, + size_t* mac_len) +{ + int ret; + yaca_ctx_h ctx = YACA_CTX_NULL; + + ret = yaca_sign_cmac_init(&ctx, algo, key); + if (ret != 0) + return ret; + + ret = sign(ctx, data, data_len, mac, mac_len); + + yaca_ctx_free(ctx); + + return ret; +} -- 2.7.4 From 20c2e824e1bd5475bea86350d8ad36337d2c06db Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Mon, 23 May 2016 10:47:53 +0200 Subject: [PATCH 12/16] Simple signature API example Change-Id: Iad04bc78c1d394bbf4c7f1e9215efb01ad365c65 --- examples/sign.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 145 insertions(+), 10 deletions(-) diff --git a/examples/sign.c b/examples/sign.c index c66e5d7..86ca1e2 100644 --- a/examples/sign.c +++ b/examples/sign.c @@ -26,11 +26,143 @@ #include #include #include +#include #include "lorem.h" #include "misc.h" #include "../src/debug.h" +// Signature creation and verification using simple API +void simple_sign_verify_asym(yaca_key_type_e type, const char *algo) +{ + char* signature = NULL; + size_t signature_len; + + yaca_key_h prv = YACA_KEY_NULL; + yaca_key_h pub = YACA_KEY_NULL; + + // GENERATE + if (yaca_key_gen(&prv, type, YACA_KEY_1024BIT) != 0) + return; + + if (yaca_key_extract_public(prv, &pub) != 0) + goto finish; + + // SIGN + if (yaca_sign(YACA_DIGEST_SHA512, + prv, + lorem4096, + LOREM4096_SIZE, + &signature, + &signature_len) != 0) + goto finish; + + dump_hex(signature, signature_len, "[Simple API] %s Signature of lorem4096:", algo); + + // VERIFY + if (yaca_verify(YACA_DIGEST_SHA512, + pub, + lorem4096, + LOREM4096_SIZE, + signature, + signature_len) != 0) + printf("[Simple API] %s verification failed\n", algo); + else + printf("[Simple API] %s verification succesful\n", algo); + +finish: + yaca_free(signature); + yaca_key_free(prv); + yaca_key_free(pub); +} + +void simple_sign_verify_hmac(void) +{ + char *signature1 = NULL; + char *signature2 = NULL; + size_t signature_len; + + yaca_key_h key = YACA_KEY_NULL; + + // GENERATE + if (yaca_key_gen(&key, YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_256BIT) != 0) + return; + + // SIGN + if (yaca_hmac(YACA_DIGEST_SHA512, + key, + lorem4096, + LOREM4096_SIZE, + &signature1, + &signature_len) != 0) + goto finish; + + dump_hex(signature1, signature_len, "[Simple API] HMAC Signature of lorem4096:"); + + // VERIFY + if (yaca_hmac(YACA_DIGEST_SHA512, + key, + lorem4096, + LOREM4096_SIZE, + &signature2, + &signature_len) != 0) + goto finish; + + if (yaca_memcmp(signature1, signature2, signature_len) != 0) + printf("[Simple API] HMAC verification failed\n"); + else + printf("[Simple API] HMAC verification succesful\n"); + +finish: + yaca_free(signature1); + yaca_free(signature2); + yaca_key_free(key); +} + +void simple_sign_verify_cmac(void) +{ + char *signature1 = NULL; + char *signature2 = NULL; + size_t signature_len; + + yaca_key_h key = YACA_KEY_NULL; + + // GENERATE + if (yaca_key_gen(&key, YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_256BIT)) + return; + + // SIGN + if (yaca_cmac(YACA_ENC_AES, + key, + lorem4096, + LOREM4096_SIZE, + &signature1, + &signature_len) != 0) + goto finish; + + dump_hex(signature1, signature_len, "[Simple API] CMAC Signature of lorem4096:"); + + + // VERIFY + if (yaca_cmac(YACA_ENC_AES, + key, + lorem4096, + LOREM4096_SIZE, + &signature2, + &signature_len) != 0) + goto finish; + + if (yaca_memcmp(signature1, signature2, signature_len) != 0) + printf("[Simple API] CMAC verification failed\n"); + else + printf("[Simple API] CMAC verification succesful\n"); + +finish: + yaca_free(signature1); + yaca_free(signature2); + yaca_key_free(key); +} + // Signature creation and verification using advanced API void sign_verify_asym(yaca_key_type_e type, const char *algo) { @@ -68,7 +200,7 @@ void sign_verify_asym(yaca_key_type_e type, const char *algo) if (yaca_sign_final(ctx, signature, &signature_len) != 0) goto finish; - dump_hex(signature, signature_len, "%s Signature of lorem4096:", algo); + dump_hex(signature, signature_len, "[Advanced API] %s Signature of lorem4096:", algo); // CLEANUP yaca_ctx_free(ctx); @@ -85,9 +217,9 @@ void sign_verify_asym(yaca_key_type_e type, const char *algo) goto finish; if (yaca_verify_final(ctx, signature, signature_len) != 0) - printf("%s verification failed\n", algo); + printf("[Advanced API] %s verification failed\n", algo); else - printf("%s verification succesful\n", algo); + printf("[Advanced API] %s verification succesful\n", algo); finish: yaca_free(signature); @@ -125,7 +257,7 @@ void sign_verify_hmac(void) if (yaca_sign_final(ctx, signature1, &signature_len) != 0) goto finish; - dump_hex(signature1, signature_len, "HMAC Signature of lorem4096:"); + dump_hex(signature1, signature_len, "[Advanced API] HMAC Signature of lorem4096:"); // CLEANUP yaca_ctx_free(ctx); @@ -148,9 +280,9 @@ void sign_verify_hmac(void) goto finish; if (yaca_memcmp(signature1, signature2, signature_len) != 0) - printf("HMAC verification failed\n"); + printf("[Advanced API] HMAC verification failed\n"); else - printf("HMAC verification succesful\n"); + printf("[Advanced API] HMAC verification succesful\n"); finish: yaca_free(signature1); @@ -188,7 +320,7 @@ void sign_verify_cmac(void) if (yaca_sign_final(ctx, signature1, &signature_len)) goto finish; - dump_hex(signature1, signature_len, "CMAC Signature of lorem4096:"); + dump_hex(signature1, signature_len, "[Advanced API] CMAC Signature of lorem4096:"); // CLEANUP yaca_ctx_free(ctx); @@ -211,9 +343,9 @@ void sign_verify_cmac(void) goto finish; if (yaca_memcmp(signature1, signature2, signature_len) != 0) - printf("CMAC verification failed\n"); + printf("[Advanced API] CMAC verification failed\n"); else - printf("CMAC verification succesful\n"); + printf("[Advanced API] CMAC verification succesful\n"); finish: yaca_free(signature1); @@ -230,7 +362,10 @@ int main() if (ret != 0) return ret; - // TODO simple? + simple_sign_verify_asym(YACA_KEY_TYPE_RSA_PRIV, "RSA"); + simple_sign_verify_asym(YACA_KEY_TYPE_DSA_PRIV, "DSA"); + simple_sign_verify_cmac(); + simple_sign_verify_hmac(); sign_verify_asym(YACA_KEY_TYPE_RSA_PRIV, "RSA"); sign_verify_asym(YACA_KEY_TYPE_DSA_PRIV, "DSA"); -- 2.7.4 From 3e4a2869b1e49f23551025d1b8b28dad8fd7d10e Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Mon, 23 May 2016 11:58:31 +0200 Subject: [PATCH 13/16] Fix code formatting in sign.c Change-Id: I767a1b32cf64ecae3f625c40c6ea83ec57368c37 --- src/sign.c | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/src/sign.c b/src/sign.c index 1a3a589..72f59b1 100644 --- a/src/sign.c +++ b/src/sign.c @@ -36,7 +36,7 @@ /* Operation type saved in context to recognize what * type of operation is performed and how to perform it. -*/ + */ enum sign_op_type { OP_SIGN = 0, OP_VERIFY = 1 @@ -64,7 +64,9 @@ static struct yaca_sign_ctx_s *get_sign_ctx(const yaca_ctx_h ctx) } } -static int get_sign_output_length(const yaca_ctx_h ctx, size_t input_len, size_t *output_len) +static int get_sign_output_length(const yaca_ctx_h ctx, + size_t input_len, + size_t *output_len) { struct yaca_sign_ctx_s *c = get_sign_ctx(ctx); @@ -103,7 +105,10 @@ static void destroy_sign_context(yaca_ctx_h ctx) c->mdctx = NULL; } -int set_sign_param(yaca_ctx_h ctx, yaca_ex_param_e param, const void *value, size_t value_len) +int set_sign_param(yaca_ctx_h ctx, + yaca_ex_param_e param, + const void *value, + size_t value_len) { int ret; struct yaca_sign_ctx_s *c = get_sign_ctx(ctx); @@ -162,7 +167,10 @@ int set_sign_param(yaca_ctx_h ctx, yaca_ex_param_e param, const void *value, siz return 0; } -int get_sign_param(const yaca_ctx_h ctx, yaca_ex_param_e param, void **value, size_t *value_len) +int get_sign_param(const yaca_ctx_h ctx, + yaca_ex_param_e param, + void **value, + size_t *value_len) { int ret; struct yaca_sign_ctx_s *c = get_sign_ctx(ctx); @@ -227,8 +235,8 @@ int get_sign_param(const yaca_ctx_h ctx, yaca_ex_param_e param, void **value, si } API 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) { struct yaca_sign_ctx_s *nc = NULL; const EVP_MD *md = NULL; @@ -300,7 +308,7 @@ API int yaca_sign_hmac_init(yaca_ctx_h *ctx, const struct yaca_key_simple_s *simple_key = key_get_simple(key); if (ctx == NULL || simple_key == NULL || - (key->type != YACA_KEY_TYPE_SYMMETRIC && key->type != YACA_KEY_TYPE_DES)) + (key->type != YACA_KEY_TYPE_SYMMETRIC && key->type != YACA_KEY_TYPE_DES)) return YACA_ERROR_INVALID_ARGUMENT; nc = yaca_zalloc(sizeof(struct yaca_sign_ctx_s)); @@ -364,7 +372,7 @@ API int yaca_sign_cmac_init(yaca_ctx_h *ctx, const struct yaca_key_simple_s *simple_key = key_get_simple(key); if (ctx == NULL || simple_key == NULL || - (key->type != YACA_KEY_TYPE_SYMMETRIC && key->type != YACA_KEY_TYPE_DES)) + (key->type != YACA_KEY_TYPE_SYMMETRIC && key->type != YACA_KEY_TYPE_DES)) return YACA_ERROR_INVALID_ARGUMENT; nc = yaca_zalloc(sizeof(struct yaca_sign_ctx_s)); @@ -440,8 +448,8 @@ free_ctx: } API int yaca_sign_update(yaca_ctx_h ctx, - const char *data, - size_t data_len) + const char *data, + size_t data_len) { struct yaca_sign_ctx_s *c = get_sign_ctx(ctx); int ret; @@ -461,8 +469,8 @@ API int yaca_sign_update(yaca_ctx_h ctx, } API int yaca_sign_final(yaca_ctx_h ctx, - char *signature, - size_t *signature_len) + char *signature, + size_t *signature_len) { struct yaca_sign_ctx_s *c = get_sign_ctx(ctx); int ret; @@ -482,8 +490,8 @@ API int yaca_sign_final(yaca_ctx_h ctx, } API 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) { struct yaca_sign_ctx_s *nc = NULL; const EVP_MD *md = NULL; @@ -544,8 +552,8 @@ free_ctx: } API int yaca_verify_update(yaca_ctx_h ctx, - const char *data, - size_t data_len) + const char *data, + size_t data_len) { struct yaca_sign_ctx_s *c = get_sign_ctx(ctx); int ret; -- 2.7.4 From d11c1e73386abe5843c196026ecf3e20c7e1f080 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Wed, 25 May 2016 17:52:09 +0200 Subject: [PATCH 14/16] Cleanup #include statements. Change-Id: I45d1600e7606915ac1408abe956e6b85d26bd5c9 --- examples/digest.c | 2 +- examples/encrypt.c | 1 + examples/key_exchange.c | 4 ++-- examples/key_import_export.c | 8 +++----- examples/misc.c | 3 ++- examples/seal.c | 1 + examples/sign.c | 1 + src/debug.c | 2 -- src/digest.c | 4 +--- src/encrypt.c | 3 --- src/internal.h | 1 + src/key.c | 11 ++++------- src/seal.c | 3 --- src/sign.c | 1 + src/simple.c | 4 ---- 15 files changed, 18 insertions(+), 31 deletions(-) diff --git a/examples/digest.c b/examples/digest.c index 9c68be3..76f0f12 100644 --- a/examples/digest.c +++ b/examples/digest.c @@ -21,11 +21,11 @@ * @brief */ -#include #include #include #include #include + #include "lorem.h" #include "misc.h" #include "../src/debug.h" diff --git a/examples/encrypt.c b/examples/encrypt.c index d436f52..ec2ee2f 100644 --- a/examples/encrypt.c +++ b/examples/encrypt.c @@ -28,6 +28,7 @@ #include #include #include + #include "lorem.h" #include "misc.h" #include "../src/debug.h" diff --git a/examples/key_exchange.c b/examples/key_exchange.c index 90c0cd3..559059e 100644 --- a/examples/key_exchange.c +++ b/examples/key_exchange.c @@ -22,11 +22,11 @@ */ #include + #include -#include #include -#include #include + #include "misc.h" #include "../src/debug.h" diff --git a/examples/key_import_export.c b/examples/key_import_export.c index 183068c..9c44266 100644 --- a/examples/key_import_export.c +++ b/examples/key_import_export.c @@ -23,15 +23,13 @@ #include -#include "misc.h" -#include "../src/debug.h" - #include -#include #include -#include #include +#include "misc.h" +#include "../src/debug.h" + int key_import_export_sym(yaca_key_h sym) { int ret; diff --git a/examples/misc.c b/examples/misc.c index 2a96106..892da72 100644 --- a/examples/misc.c +++ b/examples/misc.c @@ -25,9 +25,10 @@ #include #include +#include + #include -#include #include "misc.h" void dump_hex(const char *buf, size_t dump_size, const char *fmt, ...) diff --git a/examples/seal.c b/examples/seal.c index 2f47074..0811f43 100644 --- a/examples/seal.c +++ b/examples/seal.c @@ -27,6 +27,7 @@ #include #include #include + #include "lorem.h" #include "misc.h" #include "../src/debug.h" diff --git a/examples/sign.c b/examples/sign.c index 86ca1e2..fe56c51 100644 --- a/examples/sign.c +++ b/examples/sign.c @@ -22,6 +22,7 @@ */ #include + #include #include #include diff --git a/src/debug.c b/src/debug.c index b5f55bb..2cb0236 100644 --- a/src/debug.c +++ b/src/debug.c @@ -21,13 +21,11 @@ * @brief */ -#include #include #include #include -#include #include "internal.h" #include "debug.h" diff --git a/src/digest.c b/src/digest.c index 89eb1ff..28b095e 100644 --- a/src/digest.c +++ b/src/digest.c @@ -22,14 +22,12 @@ */ #include -#include #include -#include #include +#include #include -#include #include "internal.h" diff --git a/src/encrypt.c b/src/encrypt.c index b28c6be..f4749cd 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -22,11 +22,8 @@ */ #include -#include #include -#include -#include #include #include diff --git a/src/internal.h b/src/internal.h index 9a2a102..c010335 100644 --- a/src/internal.h +++ b/src/internal.h @@ -25,6 +25,7 @@ #define YACA_INTERNAL_H #include + #include #include diff --git a/src/key.c b/src/key.c index e3d5ffc..f31f34b 100755 --- a/src/key.c +++ b/src/key.c @@ -24,23 +24,20 @@ #include #include #include -#include #include #include -#include -#include -#include -#include - #include #include #include #include #include -#include "internal.h" +#include +#include +#include +#include "internal.h" int base64_decode_length(const char *data, size_t data_len, size_t *len) { diff --git a/src/seal.c b/src/seal.c index cbfe0ca..a3d3eb1 100644 --- a/src/seal.c +++ b/src/seal.c @@ -22,11 +22,8 @@ */ #include -#include #include -#include -#include #include #include diff --git a/src/sign.c b/src/sign.c index 72f59b1..4f749e8 100644 --- a/src/sign.c +++ b/src/sign.c @@ -29,6 +29,7 @@ #include #include +#include #include #include diff --git a/src/simple.c b/src/simple.c index 3db1098..2597c02 100644 --- a/src/simple.c +++ b/src/simple.c @@ -22,12 +22,8 @@ */ #include -#include #include -#include -#include - #include #include #include -- 2.7.4 From a889f4198a78493d4a4815733e15a05962c70536 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Fri, 27 May 2016 11:44:27 +0200 Subject: [PATCH 15/16] Remove some TODO's. Change-Id: Ic92d916f018078d1539132e0e44bd07de3e0d00c --- api/yaca/seal.h | 6 +++--- api/yaca/types.h | 1 - examples/digest.c | 2 +- examples/sign.c | 2 +- src/internal.h | 5 ++++- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/api/yaca/seal.h b/api/yaca/seal.h index bbf4ee7..2940f01 100644 --- a/api/yaca/seal.h +++ b/api/yaca/seal.h @@ -36,9 +36,9 @@ extern "C" { * * TODO: extended description and examples. * - * TODO: Seal does more than just encrypt. It first generates the encryption key and IV, - * then encrypts whole message using this key (and selected symmetric algorithm). - * Finally it encrypts symmetric key with public key. + * @remarks Seal does more than just encrypt. It first generates the encryption key and IV, + * then encrypts whole message using this key (and selected symmetric algorithm). + * Finally it encrypts symmetric key with public key. * * @{ */ diff --git a/api/yaca/types.h b/api/yaca/types.h index 7ba8cd7..0baf11c 100644 --- a/api/yaca/types.h +++ b/api/yaca/types.h @@ -92,7 +92,6 @@ typedef enum { YACA_KEY_TYPE_DH_PRIV, /**< Diffie-Hellman private key */ YACA_KEY_TYPE_EC_PUB, /**< Elliptic Curve public key (for DSA and DH) */ - YACA_KEY_TYPE_EC_PRIV, /**< Elliptic Curve private key (for DSA and DH) */ } yaca_key_type_e; diff --git a/examples/digest.c b/examples/digest.c index 76f0f12..9e01fc1 100644 --- a/examples/digest.c +++ b/examples/digest.c @@ -91,6 +91,6 @@ int main() digest_advanced(); - yaca_exit(); // TODO: what about handing of return value from exit?? + yaca_exit(); return ret; } diff --git a/examples/sign.c b/examples/sign.c index fe56c51..a6f4ee8 100644 --- a/examples/sign.c +++ b/examples/sign.c @@ -373,6 +373,6 @@ int main() sign_verify_hmac(); sign_verify_cmac(); - yaca_exit(); // TODO: what about handing of return value from exit?? + yaca_exit(); return ret; } diff --git a/src/internal.h b/src/internal.h index c010335..16b8b38 100644 --- a/src/internal.h +++ b/src/internal.h @@ -82,8 +82,11 @@ struct yaca_key_simple_s * - YACA_KEY_TYPE_RSA_PRIV * - YACA_KEY_TYPE_DSA_PUB * - YACA_KEY_TYPE_DSA_PRIV + * - YACA_KEY_TYPE_DH_PUB + * - YACA_KEY_TYPE_DH_PRIV + * - YACA_KEY_TYPE_EC_PUB + * - YACA_KEY_TYPE_EC_PRIV * - * TODO: and possibly others (for every key that uses EVP_PKEY) */ struct yaca_key_evp_s { -- 2.7.4 From 6774154ef5d67b88df0c16d46fe40f205694ccee Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Mon, 16 May 2016 14:54:35 +0200 Subject: [PATCH 16/16] Add support to AES GCM/CCM. Update documentation. Change-Id: Ifecf73fe15061afe8ad28a9ad20abc79f518f387 --- api/yaca/encrypt.h | 2 - api/yaca/simple.h | 2 +- api/yaca/types.h | 53 ++++++++++++++--- src/encrypt.c | 169 ++++++++++++++++++++++++++++++++++++++++++++++------- 4 files changed, 194 insertions(+), 32 deletions(-) diff --git a/api/yaca/encrypt.h b/api/yaca/encrypt.h index cc07262..de7bc58 100644 --- a/api/yaca/encrypt.h +++ b/api/yaca/encrypt.h @@ -36,8 +36,6 @@ extern "C" { * * TODO: extended description and examples. * - * TODO: Let's describe how to set additional params (like GCM, CCM) - * * @{ */ diff --git a/api/yaca/simple.h b/api/yaca/simple.h index b43a60b..9c62314 100644 --- a/api/yaca/simple.h +++ b/api/yaca/simple.h @@ -39,7 +39,7 @@ extern "C" { * - All operations are single-shot (no streaming possible) * - Context is not used * - For now only digest and symmetric ciphers are supported - * - GCM chaining is not supported + * - GCM and CCM chaining is not supported * - All outputs are allocated by the library * * TODO: extended description and examples. diff --git a/api/yaca/types.h b/api/yaca/types.h index 0baf11c..70a097d 100644 --- a/api/yaca/types.h +++ b/api/yaca/types.h @@ -273,11 +273,27 @@ typedef enum { YACA_BCM_CBC, /** - * GCM block cipher mode, IV is needed. + * GCM block cipher mode. + * This is a variable IV length mode (recommended 96 bits IV). + * * 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_PARAM_GCM_TAG_LEN = GCM tag length\n + * Supported tag lengths: @c 32, @c 64, @c 96, @c 104, @c 112, @c 120, @c 128, + * (recommended 128 bits tag).\n + * Set after yaca_encrypt_final() and before yaca_ctx_get_param(#YACA_PARAM_GCM_TAG) + * in encryption operation.\n\n + * + * - #YACA_PARAM_GCM_TAG = GCM tag\n + * Get after yaca_encrypt_final() in encryption operation.\n + * Set before yaca_decrypt_final() in decryption operation.\n\n + * + * - #YACA_PARAM_GCM_AAD = additional authentication data (optional)\n + * Set after yaca_encrypt_init() and before yaca_encrypt_update() + * in encryption operation.\n + * Set after yaca_decrypt_init() and before yaca_decrypt_update() + * in decryption operation.\n\n + * + * @see examples/encrypt_aes_gcm_ccm.c */ YACA_BCM_GCM, @@ -307,10 +323,33 @@ typedef enum { /** * CBC-MAC Mode (AES). + * This is a variable IV length mode.\n + * Supported IV lengths: 56-104 bits in steps of 8 bits (recommended 56 bits IV).\n\n + * * 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_PARAM_CCM_TAG_LEN = CCM tag length\n + * Supported tag lengths: 32-128 bits in step of 16 bits (recommended 96 bits tag).\n + * Set after yaca_encrypt_init() and before yaca_encrypt_update() + * in encryption operation.\n\n + * + * - #YACA_PARAM_CCM_TAG = CCM tag\n + * Get after yaca_encrypt_final() in encryption operation.\n + * Set after yaca_decrypt_init() and before yaca_decrypt_update() + * in decryption operation.\n\n + * + * - #YACA_PARAM_CCM_AAD = additional authentication data (optional)\n + * The total plain text length must be passed to yaca_encrypt_update() + * if AAD is used.\n + * Set after yaca_encrypt_init() and before yaca_encrypt_update() + * in encryption operation.\n + * You can only call yaca_encrypt_update() once for AAD and once for the plain text.\n\n + * + * The total encrypted text length must be passed to yaca_decrypt_update() + * if AAD is used.\n + * Set after yaca_decrypt_init() and before yaca_decrypt_update() + * in decryption operation.\n\n + * + * @see examples/encrypt_aes_gcm_ccm.c */ YACA_BCM_CCM diff --git a/src/encrypt.c b/src/encrypt.c index f4749cd..c3d93ee 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -44,6 +44,7 @@ struct yaca_encrypt_ctx_s EVP_CIPHER_CTX *cipher_ctx; enum encrypt_op_type op_type; /* Operation context was created for */ + size_t tag_len; }; static struct yaca_encrypt_ctx_s *get_encrypt_ctx(const yaca_ctx_h ctx) @@ -76,8 +77,9 @@ static int get_encrypt_output_length(const yaca_ctx_h ctx, size_t input_len, siz struct yaca_encrypt_ctx_s *nc = get_encrypt_ctx(ctx); int block_size; - if (nc == NULL || nc->cipher_ctx == NULL) + if (nc == NULL) return YACA_ERROR_INVALID_ARGUMENT; + assert(nc->cipher_ctx != NULL); block_size = EVP_CIPHER_CTX_block_size(nc->cipher_ctx); if (block_size <= 0) { @@ -97,6 +99,107 @@ static int get_encrypt_output_length(const yaca_ctx_h ctx, size_t input_len, siz return 0; } +static int set_encrypt_param(yaca_ctx_h ctx, + yaca_ex_param_e param, + const void *value, + size_t value_len) +{ + struct yaca_encrypt_ctx_s *c = get_encrypt_ctx(ctx); + int len; + + if (c == NULL || value == NULL) + return YACA_ERROR_INVALID_ARGUMENT; + assert(c->cipher_ctx != NULL); + + switch(param) + { + case YACA_PARAM_GCM_AAD: + case YACA_PARAM_CCM_AAD: + if (EVP_EncryptUpdate(c->cipher_ctx, NULL, &len, value, value_len) != 1) { + ERROR_DUMP(YACA_ERROR_INTERNAL); + return YACA_ERROR_INTERNAL; + } + break; + case YACA_PARAM_GCM_TAG: + if (EVP_CIPHER_CTX_ctrl(c->cipher_ctx, + EVP_CTRL_GCM_SET_TAG, + value_len, (void*)value) != 1) { + ERROR_DUMP(YACA_ERROR_INTERNAL); + return YACA_ERROR_INTERNAL; + } + break; + case YACA_PARAM_GCM_TAG_LEN: + c->tag_len = *(int*)value; + break; + case YACA_PARAM_CCM_TAG: + // TODO Rebuild context + if (EVP_CIPHER_CTX_ctrl(c->cipher_ctx, + EVP_CTRL_CCM_SET_TAG, + value_len, (void*)value) != 1) { + ERROR_DUMP(YACA_ERROR_INTERNAL); + return YACA_ERROR_INTERNAL; + } + break; + case YACA_PARAM_CCM_TAG_LEN: + //TODO Rebuild context + if (EVP_CIPHER_CTX_ctrl(c->cipher_ctx, + EVP_CTRL_CCM_SET_TAG, + value_len, NULL) != 1) { + ERROR_DUMP(YACA_ERROR_INTERNAL); + return YACA_ERROR_INTERNAL; + } + c->tag_len = *(int*)value; + break; + default: + return YACA_ERROR_INVALID_ARGUMENT; + } + return 0; +} + +static int get_encrypt_param(const yaca_ctx_h ctx, + yaca_ex_param_e param, + void **value, + size_t *value_len) +{ + struct yaca_encrypt_ctx_s *c = get_encrypt_ctx(ctx); + + if (c == NULL || value == NULL || value_len == NULL) + return YACA_ERROR_INVALID_ARGUMENT; + assert(c->cipher_ctx != NULL); + + switch(param) + { + case YACA_PARAM_GCM_TAG: + if (c->tag_len == 0) + return YACA_ERROR_INVALID_ARGUMENT; + + if (EVP_CIPHER_CTX_ctrl(c->cipher_ctx, + EVP_CTRL_GCM_GET_TAG, + c->tag_len, value) != 1) { + ERROR_DUMP(YACA_ERROR_INTERNAL); + return YACA_ERROR_INTERNAL; + } + *value_len = c->tag_len; + break; + case YACA_PARAM_CCM_TAG: + if (c->tag_len == 0) + return YACA_ERROR_INVALID_ARGUMENT; + + if (EVP_CIPHER_CTX_ctrl(c->cipher_ctx, + EVP_CTRL_CCM_GET_TAG, + c->tag_len, value) != 1) { + ERROR_DUMP(YACA_ERROR_INTERNAL); + return YACA_ERROR_INTERNAL; + } + *value_len = c->tag_len; + break; + default: + return YACA_ERROR_INVALID_ARGUMENT; + break; + } + return 0; +} + static const char *encrypt_algo_to_str(yaca_enc_algo_e algo) { switch(algo) @@ -240,7 +343,10 @@ static int encrypt_init(yaca_ctx_h *ctx, nc->ctx.type = YACA_CTX_ENCRYPT; nc->ctx.ctx_destroy = destroy_encrypt_ctx; nc->ctx.get_output_length = get_encrypt_output_length; + nc->ctx.set_param = set_encrypt_param; + nc->ctx.get_param = get_encrypt_param; nc->op_type = op_type; + nc->tag_len = 0; ret = yaca_key_get_bits(sym_key, &key_bits); if (ret != 0) @@ -274,7 +380,10 @@ static int encrypt_init(yaca_ctx_h *ctx, ret = YACA_ERROR_INVALID_ARGUMENT; goto err_free; } - if (iv_bits != iv_bits_check) { /* IV length doesn't match cipher */ + /* IV length doesn't match cipher (GCM & CCM supports variable IV length) */ + if (iv_bits != iv_bits_check && + bcm != YACA_BCM_GCM && + bcm != YACA_BCM_CCM) { ret = YACA_ERROR_INVALID_ARGUMENT; goto err_free; } @@ -291,39 +400,56 @@ static int encrypt_init(yaca_ctx_h *ctx, switch (op_type) { case OP_ENCRYPT: ret = EVP_EncryptInit_ex(nc->cipher_ctx, cipher, NULL, NULL, NULL); - if (ret != 1) - break; + break; + case OP_DECRYPT: + ret = EVP_DecryptInit_ex(nc->cipher_ctx, cipher, NULL, NULL, NULL); + break; + default: + ret = YACA_ERROR_INVALID_ARGUMENT; + goto err_ctx; + } + + if (ret != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto err_ctx; + } + + /* Handling of algorithms with variable key length */ + ret = EVP_CIPHER_CTX_set_key_length(nc->cipher_ctx, key_bits / 8); + if (ret != 1) { + ret = YACA_ERROR_INVALID_ARGUMENT; + ERROR_DUMP(ret); + goto err_ctx; + } + + /* Handling of algorithms with variable IV length */ + if (iv_bits != iv_bits_check) { + if (bcm == YACA_BCM_GCM) + ret = EVP_CIPHER_CTX_ctrl(nc->cipher_ctx, EVP_CTRL_GCM_SET_IVLEN, + iv_bits_check / 8, NULL); + + if (bcm == YACA_BCM_CCM) + ret = EVP_CIPHER_CTX_ctrl(nc->cipher_ctx, EVP_CTRL_CCM_SET_IVLEN, + iv_bits_check / 8, NULL); - /* Handling of algorithms with variable key length */ - ret = EVP_CIPHER_CTX_set_key_length(nc->cipher_ctx, key_bits / 8); if (ret != 1) { ret = YACA_ERROR_INVALID_ARGUMENT; ERROR_DUMP(ret); goto err_ctx; } + } + switch (op_type) { + case OP_ENCRYPT: ret = EVP_EncryptInit_ex(nc->cipher_ctx, NULL, NULL, (unsigned char*)lkey->d, iv_data); - break; case OP_DECRYPT: - ret = EVP_DecryptInit_ex(nc->cipher_ctx, cipher, NULL, NULL, NULL); - if (ret != 1) - break; - - /* Handling of algorithms with variable key length */ - ret = EVP_CIPHER_CTX_set_key_length(nc->cipher_ctx, key_bits / 8); - if (ret != 1) { - ret = YACA_ERROR_INVALID_ARGUMENT; - ERROR_DUMP(ret); - goto err_ctx; - } - ret = EVP_DecryptInit_ex(nc->cipher_ctx, NULL, NULL, (unsigned char*)lkey->d, iv_data); - break; default: ret = YACA_ERROR_INVALID_ARGUMENT; @@ -357,8 +483,7 @@ static int encrypt_update(yaca_ctx_h ctx, int ret; int loutput_len; - if (c == NULL || input == NULL || input_len == 0 || - output == NULL || output_len == NULL || op_type != c->op_type) + if (c == NULL || input_len == 0 || output_len == NULL || op_type != c->op_type) return YACA_ERROR_INVALID_ARGUMENT; loutput_len = *output_len; -- 2.7.4