From 82a68c8a8ab4ca140798a192c8086318ae915b00 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Mon, 9 May 2016 12:42:54 +0200 Subject: [PATCH 01/16] yaca_key_import()/yaca_key_export() for DSA It seems that my previous import/export commit was generic enough to handle DSA as well. Only minor change was required to enable DSA. That's why this commit is so short. Change-Id: I0627c10a723b0011dde705d74d290caa36533a9d --- src/key.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/key.c b/src/key.c index 00a26d3..2406350 100644 --- a/src/key.c +++ b/src/key.c @@ -777,10 +777,10 @@ API int yaca_key_import(yaca_key_h *key, 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: + return import_evp(key, key_type, data, data_len); + case YACA_KEY_TYPE_DES: case YACA_KEY_TYPE_DH_PUB: case YACA_KEY_TYPE_DH_PRIV: case YACA_KEY_TYPE_ECDSA_PUB: -- 2.7.4 From d98b1aa22ed766ef6c311efc5940f11a13750d43 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Mon, 9 May 2016 13:20:54 +0200 Subject: [PATCH 02/16] Add DSA to import/export example Improved printing a little. This example can serve partially as a test. It has been written this way as a verification tool as we don't have proper tests yet. Change-Id: Ifbda0f17e2e8fc0b734d34d49668a4a7662c337d --- examples/key_import_export.c | 100 +++++++++++++++++++++++++++++++------------ 1 file changed, 73 insertions(+), 27 deletions(-) diff --git a/examples/key_import_export.c b/examples/key_import_export.c index 57b231c..6dc18e1 100644 --- a/examples/key_import_export.c +++ b/examples/key_import_export.c @@ -31,7 +31,7 @@ #include #include -void key_import_export_sym(yaca_key_h sym) +int key_import_export_sym(yaca_key_h sym) { int ret; @@ -48,12 +48,12 @@ void key_import_export_sym(yaca_key_h sym) ret = yaca_key_export(sym, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_BASE64, &b64, &b64_len); if (ret != 0) - return; + return ret; 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); + printf("\n\t***** BASE64 exported key: *****\n%.*s\n", (int)b64_len, b64); yaca_free(b64); b64 = NULL; @@ -61,7 +61,7 @@ void key_import_export_sym(yaca_key_h sym) if (ret != 0) goto free; - printf("\t***** BASE64 imported key: *****\n%*s\n", (int)b64_len, b64); + printf("\t***** BASE64 imported key: *****\n%.*s\n", (int)b64_len, b64); /* RAW */ @@ -83,14 +83,20 @@ void key_import_export_sym(yaca_key_h sym) dump_hex(raw, raw_len, "\t***** RAW imported key: *****"); + ret = 0; + free: yaca_key_free(raw_imported); yaca_key_free(b64_imported); yaca_free(raw); yaca_free(b64); + + return ret; } -void key_import_export_rsa(yaca_key_h priv, yaca_key_h pub) +int key_import_export_asym(yaca_key_h priv, yaca_key_h pub, + yaca_key_type_e priv_type, yaca_key_type_e pub_type, + const char *algo) { int ret; @@ -114,12 +120,12 @@ void key_import_export_rsa(yaca_key_h priv, yaca_key_h pub) 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); + return ret; + ret = yaca_key_import(&pem_prv_imported, priv_type, 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); + printf("\n\t***** %s PEM exported private key: *****\n%.*s", algo, (int)pem_prv_len, pem_prv); yaca_free(pem_prv); pem_prv = NULL; @@ -127,7 +133,7 @@ void key_import_export_rsa(yaca_key_h priv, yaca_key_h pub) if (ret != 0) goto free; - printf("\t***** PEM imported private key: *****\n%*s", (int)pem_prv_len, pem_prv); + printf("\t***** %s PEM imported private key: *****\n%.*s", algo, (int)pem_prv_len, pem_prv); /* DER private */ @@ -135,11 +141,11 @@ void key_import_export_rsa(yaca_key_h priv, yaca_key_h pub) 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); + ret = yaca_key_import(&der_prv_imported, priv_type, der_prv, der_prv_len); if (ret != 0) goto free; - dump_hex(der_prv, der_prv_len, "\n\t***** DER exported private key: *****"); + dump_hex(der_prv, der_prv_len, "\n\t***** %s DER exported private key: *****", algo); yaca_free(der_prv); der_prv = NULL; @@ -147,7 +153,7 @@ void key_import_export_rsa(yaca_key_h priv, yaca_key_h pub) if (ret != 0) goto free; - dump_hex(der_prv, der_prv_len, "\t***** DER imported private key: *****"); + dump_hex(der_prv, der_prv_len, "\t***** %s DER imported private key: *****", algo); /* PEM public */ @@ -155,11 +161,11 @@ void key_import_export_rsa(yaca_key_h priv, yaca_key_h pub) 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); + ret = yaca_key_import(&pem_pub_imported, pub_type, 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); + printf("\n\t***** %s PEM exported public key: *****\n%.*s", algo, (int)pem_pub_len, pem_pub); yaca_free(pem_pub); pem_pub = NULL; @@ -167,7 +173,7 @@ void key_import_export_rsa(yaca_key_h priv, yaca_key_h pub) if (ret != 0) goto free; - printf("\t***** PEM imported public key: *****\n%*s", (int)pem_pub_len, pem_pub); + printf("\t***** %s PEM imported public key: *****\n%.*s", algo, (int)pem_pub_len, pem_pub); /* DER public */ @@ -175,11 +181,11 @@ void key_import_export_rsa(yaca_key_h priv, yaca_key_h pub) 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); + ret = yaca_key_import(&der_pub_imported, pub_type, der_pub, der_pub_len); if (ret != 0) goto free; - dump_hex(der_pub, der_pub_len, "\n\t***** DER exported public key: *****"); + dump_hex(der_pub, der_pub_len, "\n\t***** %s DER exported public key: *****", algo); yaca_free(der_pub); der_pub = NULL; @@ -187,7 +193,9 @@ void key_import_export_rsa(yaca_key_h priv, yaca_key_h pub) if (ret != 0) goto free; - dump_hex(der_pub, der_pub_len, "\t***** DER imported public key: *****"); + dump_hex(der_pub, der_pub_len, "\t***** %s DER imported public key: *****", algo); + + ret = 0; free: yaca_key_free(der_pub_imported); @@ -198,13 +206,17 @@ free: yaca_free(pem_pub); yaca_free(der_prv); yaca_free(pem_prv); + + return ret; } int main() { - yaca_key_h sym; - yaca_key_h rsa_priv; - yaca_key_h rsa_pub; + yaca_key_h sym = YACA_KEY_NULL; + yaca_key_h rsa_priv = YACA_KEY_NULL; + yaca_key_h rsa_pub = YACA_KEY_NULL; + yaca_key_h dsa_priv = YACA_KEY_NULL; + yaca_key_h dsa_pub = YACA_KEY_NULL; int ret; ret = yaca_init(); @@ -219,18 +231,52 @@ int main() ret = yaca_key_gen(&rsa_priv, YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_1024BIT); if (ret != 0) - goto free_sym; + goto free; ret = yaca_key_extract_public(rsa_priv, &rsa_pub); if (ret != 0) - goto free_sym; + goto free; - key_import_export_sym(sym); - key_import_export_rsa(rsa_priv, rsa_pub); + ret = yaca_key_gen(&dsa_priv, YACA_KEY_TYPE_DSA_PRIV, YACA_KEY_1024BIT); + if (ret != 0) + goto free; - yaca_key_free(rsa_priv); + ret = yaca_key_extract_public(dsa_priv, &dsa_pub); + if (ret != 0) + goto free; + + printf("\t***************************************\n"); + printf("\t************** SYMMETRIC **************\n"); + printf("\t***************************************\n"); + ret = key_import_export_sym(sym); + if (ret == 0) + printf("\n\t********* SYMMETRIC - success *********\n\n"); + else + printf("\n\t********* SYMMETRIC - failure *********\n\n"); + + printf("\t***************************************\n"); + printf("\t***************** RSA *****************\n"); + printf("\t***************************************\n"); + ret = key_import_export_asym(rsa_priv, rsa_pub, YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_TYPE_RSA_PUB, "RSA"); + if (ret == 0) + printf("\n\t************ RSA - success ************\n\n"); + else + printf("\n\t************ RSA - failure ************\n\n"); + + printf("\t***************************************\n"); + printf("\t***************** DSA *****************\n"); + printf("\t***************************************\n"); + ret = key_import_export_asym(dsa_priv, dsa_pub, YACA_KEY_TYPE_DSA_PRIV, YACA_KEY_TYPE_DSA_PUB, "DSA"); + if (ret == 0) + printf("\n\t************ DSA - success ************\n\n"); + else + printf("\n\t************ DSA - failure ************\n\n"); + +free: + yaca_key_free(dsa_pub); + yaca_key_free(dsa_priv); yaca_key_free(rsa_pub); -free_sym: + yaca_key_free(rsa_priv); yaca_key_free(sym); exit: yaca_exit(); -- 2.7.4 From 3fe61dca1147ecad93699d4d27bc12bc7ece3f65 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Mon, 9 May 2016 13:27:08 +0200 Subject: [PATCH 03/16] DSA sign/verify support The previous implementation was generic enough to handle DSA as well. Change-Id: I0c952e340cae3fabb05aa0e10fa5f0947319e4f8 --- src/sign.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sign.c b/src/sign.c index 24fe7ac..b885cc6 100644 --- a/src/sign.c +++ b/src/sign.c @@ -157,9 +157,9 @@ API int yaca_sign_init(yaca_ctx_h *ctx, { 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_DSA_PRIV: case YACA_KEY_TYPE_ECDSA_PRIV: ret = YACA_ERROR_NOT_IMPLEMENTED; goto free_ctx; @@ -277,9 +277,9 @@ API int yaca_verify_init(yaca_ctx_h *ctx, 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_DSA_PUB: case YACA_KEY_TYPE_ECDSA_PUB: ret = YACA_ERROR_NOT_IMPLEMENTED; goto free_ctx; -- 2.7.4 From 5d39a9bd90ad8c1f97ccd24aa62a6c90c5a055b6 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Mon, 9 May 2016 13:29:05 +0200 Subject: [PATCH 04/16] DSA sign/verify example Change-Id: I29208ed486b03f40af4a1ddd52f999b3c6d25a99 --- examples/sign.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/examples/sign.c b/examples/sign.c index 84d5574..c5c9a5e 100644 --- a/examples/sign.c +++ b/examples/sign.c @@ -33,7 +33,7 @@ #define PADDING_IMPLEMENTED 0 // Signature creation and verification using advanced API -void sign_verify_rsa(void) +void sign_verify_asym(yaca_key_type_e type, const char *algo) { char* signature = NULL; size_t signature_len; @@ -46,7 +46,7 @@ void sign_verify_rsa(void) #endif // GENERATE - if (yaca_key_gen(&prv, YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_4096BIT) != 0) + if (yaca_key_gen(&prv, type, YACA_KEY_4096BIT) != 0) return; if (yaca_key_extract_public(prv, &pub) != 0) @@ -74,7 +74,7 @@ void sign_verify_rsa(void) if (yaca_sign_final(ctx, signature, &signature_len) != 0) goto finish; - dump_hex(signature, signature_len, "RSA Signature of lorem4096:"); + dump_hex(signature, signature_len, "%s Signature of lorem4096:", algo); // CLEANUP yaca_ctx_free(ctx); @@ -93,9 +93,9 @@ void sign_verify_rsa(void) goto finish; if (yaca_verify_final(ctx, signature, signature_len) != 0) - printf("RSA verification failed\n"); + printf("%s verification failed\n", algo); else - printf("RSA verification succesful\n"); + printf("%s verification succesful\n", algo); finish: yaca_free(signature); @@ -219,7 +219,8 @@ int main() // TODO simple? - sign_verify_rsa(); + sign_verify_asym(YACA_KEY_TYPE_RSA_PRIV, "RSA"); + sign_verify_asym(YACA_KEY_TYPE_DSA_PRIV, "DSA"); sign_verify_hmac(); sign_verify_cmac(); -- 2.7.4 From 0a41580e6f4b9fa048450f697f7bca36e895f2b8 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Mon, 9 May 2016 14:08:35 +0200 Subject: [PATCH 05/16] Use specific RSA/DSA export variants The reason is, that the output of a PEM is different in the case of PrivateKey variant and DSAPrivateKey and RSAPrivateKey variants. According to the manual they should behave the same way. They don't. They seem to be in a different ASN1 format. This change is to be consistent with the default behaviour of the command line tool. This problem does not seem to appear on DER keys, but just for consistency and to be safe do the same there. Change-Id: I6a765e831515e9aac0353595132a139aec7b38d2 --- src/key.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/key.c b/src/key.c index 2406350..3327ba4 100644 --- a/src/key.c +++ b/src/key.c @@ -428,8 +428,12 @@ int export_evp(struct yaca_key_evp_s *evp_key, switch (evp_key->key.type) { case YACA_KEY_TYPE_RSA_PRIV: + ret = PEM_write_bio_RSAPrivateKey(mem, EVP_PKEY_get0(evp_key->evp), + NULL, NULL, 0, NULL, NULL); + break; case YACA_KEY_TYPE_DSA_PRIV: - ret = PEM_write_bio_PrivateKey(mem, evp_key->evp, NULL, NULL, 0, NULL, NULL); + ret = PEM_write_bio_DSAPrivateKey(mem, EVP_PKEY_get0(evp_key->evp), + NULL, NULL, 0, NULL, NULL); break; case YACA_KEY_TYPE_RSA_PUB: @@ -457,8 +461,11 @@ int export_evp(struct yaca_key_evp_s *evp_key, switch (evp_key->key.type) { case YACA_KEY_TYPE_RSA_PRIV: + ret = i2d_RSAPrivateKey_bio(mem, EVP_PKEY_get0(evp_key->evp)); + break; + case YACA_KEY_TYPE_DSA_PRIV: - ret = i2d_PrivateKey_bio(mem, evp_key->evp); + ret = i2d_DSAPrivateKey_bio(mem, EVP_PKEY_get0(evp_key->evp)); break; case YACA_KEY_TYPE_RSA_PUB: -- 2.7.4 From 92eb4e64e351bbdf04ad7049fc5f970b51a36d8a Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Mon, 9 May 2016 15:50:58 +0200 Subject: [PATCH 06/16] Add support for importing public keys from X509 certificate Fix a bug with X509 not being freed and pkey not being freed in case of an error. Change-Id: I063f606b928c679c452347cc18db793fc066c509 --- src/key.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/key.c b/src/key.c index 3327ba4..db8b6c4 100644 --- a/src/key.c +++ b/src/key.c @@ -221,6 +221,7 @@ int import_evp(yaca_key_h *key, assert(data != NULL); assert(data_len != 0); + int ret; BIO *src = NULL; EVP_PKEY *pkey = NULL; bool private; @@ -257,6 +258,15 @@ int import_evp(yaca_key_h *key, pkey = PEM_read_bio_PUBKEY(src, NULL, NULL, NULL); private = false; } + + if (pkey == NULL) { + BIO_reset(src); + X509 *x509 = PEM_read_bio_X509(src, NULL, NULL, NULL); + if (x509 != NULL) + pkey = X509_get_pubkey(x509); + private = false; + X509_free(x509); + } } /* Possible DER */ else { @@ -292,21 +302,31 @@ int import_evp(yaca_key_h *key, break; default: - return YACA_ERROR_INVALID_ARGUMENT; + ret = YACA_ERROR_INVALID_ARGUMENT; + goto free; } - if (type != key_type) - return YACA_ERROR_INVALID_ARGUMENT; + if (type != key_type) { + ret = YACA_ERROR_INVALID_ARGUMENT; + goto free; + } nk = yaca_zalloc(sizeof(struct yaca_key_evp_s)); - if (nk == NULL) - return YACA_ERROR_OUT_OF_MEMORY; + if (nk == NULL) { + ret = YACA_ERROR_OUT_OF_MEMORY; + goto free; + } nk->evp = pkey; *key = (yaca_key_h)nk; (*key)->type = type; - return 0; + pkey = NULL; + ret = 0; + +free: + EVP_PKEY_free(pkey); + return ret; } int export_simple_raw(struct yaca_key_simple_s *simple_key, -- 2.7.4 From 95c02cc487f8c792d99eba6c9f4351fa3317844d Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Mon, 9 May 2016 15:51:40 +0200 Subject: [PATCH 07/16] Example for X509 import Change-Id: I698b81ff87ca4f2579447a8085a2a2ba2f0cb3ee --- examples/key_import_export.c | 45 ++++++++++++++++++++++++++++++++++++++++++++ examples/x509.crt | 21 +++++++++++++++++++++ examples/x509.key | 28 +++++++++++++++++++++++++++ 3 files changed, 94 insertions(+) create mode 100644 examples/x509.crt create mode 100644 examples/x509.key diff --git a/examples/key_import_export.c b/examples/key_import_export.c index 6dc18e1..1c4db07 100644 --- a/examples/key_import_export.c +++ b/examples/key_import_export.c @@ -210,6 +210,42 @@ free: return ret; } +int key_import_x509(void) +{ + int ret; + char *pub = NULL; + size_t pub_len; + yaca_key_h rsa_pub_from_cert = YACA_KEY_NULL; + + ret = read_file("x509.crt", &pub, &pub_len); + if (ret != 0) { + printf("Make sure you copied a x509.crt from yaca_root/examples to your current directory\n"); + printf("You can also generate one with:\n"); + printf("openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout x509.key -out x509.crt\n"); + return ret; + } + + ret = yaca_key_import(&rsa_pub_from_cert, YACA_KEY_TYPE_RSA_PUB, pub, pub_len); + if (ret != 0) + goto free; + + yaca_free(pub); + pub = NULL; + + ret = yaca_key_export(rsa_pub_from_cert, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_PEM, &pub, &pub_len); + if (ret != 0) + goto free; + + printf("\n\t***** RSA X509 imported public key: *****\n%.*s", (int)pub_len, pub); + + ret = 0; + +free: + yaca_key_free(rsa_pub_from_cert); + yaca_free(pub); + return ret; +} + int main() { yaca_key_h sym = YACA_KEY_NULL; @@ -272,6 +308,15 @@ int main() else printf("\n\t************ DSA - failure ************\n\n"); + printf("\t***************************************\n"); + printf("\t**************** X509 *****************\n"); + printf("\t***************************************\n"); + ret = key_import_x509(); + if (ret == 0) + printf("\n\t*********** X509 - success ************\n\n"); + else + printf("\n\t*********** X509 - failure ************\n\n"); + free: yaca_key_free(dsa_pub); yaca_key_free(dsa_priv); diff --git a/examples/x509.crt b/examples/x509.crt new file mode 100644 index 0000000..f421e11 --- /dev/null +++ b/examples/x509.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDiTCCAnGgAwIBAgIJAMmTp8b7IBZ4MA0GCSqGSIb3DQEBCwUAMFsxCzAJBgNV +BAYTAlBMMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxEDAOBgNVBAoMB1NhbXN1bmcx +CzAJBgNVBAsMAlJEMRYwFAYDVQQDDA15YWNhLnRlc3Qua2V5MB4XDTE2MDUwOTE0 +MDUwM1oXDTE3MDUwOTE0MDUwM1owWzELMAkGA1UEBhMCUEwxFTATBgNVBAcMDERl +ZmF1bHQgQ2l0eTEQMA4GA1UECgwHU2Ftc3VuZzELMAkGA1UECwwCUkQxFjAUBgNV +BAMMDXlhY2EudGVzdC5rZXkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQC7729iOIdGcnuTba8nq1G4HF8isCR/8K/vtclsoCjAxQph5ANa+/9gbIFdQmmn +MBhSOckl9Tl/a9g/2b/vbezo2qXAuaeOPNr/ZF6Z+h7yPJids7WmBAPphzHeIKQf +kr2KLRbFYIIGF4mC/JfNOBzh8ChcklxnUJu4W8bJPrPkr3zlcMqxpRCCXAqIUxh7 +lCDta7Uoip+VcibRqh8g7+eZmTu3GwWtZQCB9kq5BijfguxxDHAXyQ6g7gxOZpwA +BP9AXdB7K1KAoeBf0e/lUjC1eXkhvno9TJSp2Q7LEIJqEe/Khyj4FG4KrOu/ifpS +wpGP1ztzdMcY5UGwSbtEwMqvAgMBAAGjUDBOMB0GA1UdDgQWBBTtvbhve2aaeNIL +0eYjakjeEGMCsDAfBgNVHSMEGDAWgBTtvbhve2aaeNIL0eYjakjeEGMCsDAMBgNV +HRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBj9LtBvK6P65J/1jEfSajvoIip +ZtpW38KbRkgencq9bFeNONMHGv5M7tEnWNdytCPunlh5DLEXMUORcWfXU73GCNHO +9So74rri+q8NKrllJWxWmbYoAo+zJ3xSJ0PKhU8SW6J+dfPvsg140bUXI+MbOGrr +ski88TRVnBOb3HBU1Vd+A2W7YKy9j2ykQH4NiIUPV01h3hguvMLcLzHZ6LN/BHnA +NQx/K/EVIHZxy1ez8vbbIuWW5MRj6SPeofyZC0QoxQGIT6sGDZSNDP6xIGVuKw4D +UpzPNfCvsWgNIaIFTTzLBZJYCwoexJYIO+NiaJxCV9l3swj2iUA3yeyNQZhI +-----END CERTIFICATE----- diff --git a/examples/x509.key b/examples/x509.key new file mode 100644 index 0000000..e2d8ae1 --- /dev/null +++ b/examples/x509.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC7729iOIdGcnuT +ba8nq1G4HF8isCR/8K/vtclsoCjAxQph5ANa+/9gbIFdQmmnMBhSOckl9Tl/a9g/ +2b/vbezo2qXAuaeOPNr/ZF6Z+h7yPJids7WmBAPphzHeIKQfkr2KLRbFYIIGF4mC +/JfNOBzh8ChcklxnUJu4W8bJPrPkr3zlcMqxpRCCXAqIUxh7lCDta7Uoip+VcibR +qh8g7+eZmTu3GwWtZQCB9kq5BijfguxxDHAXyQ6g7gxOZpwABP9AXdB7K1KAoeBf +0e/lUjC1eXkhvno9TJSp2Q7LEIJqEe/Khyj4FG4KrOu/ifpSwpGP1ztzdMcY5UGw +SbtEwMqvAgMBAAECggEBAJhdhZM/O0U9Gb0sJt5lggpfTi4kWmMzsqAIZPZhXsjy +tvkoUCQavC/jqHoAlwHJ913qpY7VorkQqTETDA5Es9cRNWLr4dFquy5lpGD3rNE9 +mYn5oeKnzLgvOJnbItTKNkrpRVXeaWwg9wawXS4vORNgjoiGzM2iR62PEroj0Nss +mwua2xs92ZHTAMNH6PdJC9U4gqjmlAMofV7ZgpxJLzKsI4rbxcGk9NWrie5bmMu+ +SECwtFDqxHe7YJRjSOvz/HErbXg9qWsglU6PFCVUjQ2dLM4k78ORkR5hvpGYGc83 +DucbEGqOnQ37RACvgNX4/RGFMvVnJDx3FVoDMcz2NFECgYEA6jEiY5RZuUy7jIBR +t1RFTem0KUFco7YLxwHacrT66vEntc1REXeBYSMPeKav1R319jxVVD7iiF4w49Ol +4VxxgPBUhfHou/ZU5S5xLbWRrJG0jvUPUKNVebNCqbv1YXhzf6kRn1vE5j+MR9ge +YMMFG1Si3VXoUm5+IInj1b2mC5kCgYEAzW+YiRJpEbl0+2gNCcHTAhr2cA1t6mdL +9/JGkUhHqwGhMAByZr1QFJeOTLKR9cSNS1FYOJu6wUetnkYDvNgx7gnsiJ50TEof +poTZgtnFCxgGwcEFL23L0PPim5CEUMHRti4j+Wlb8FzTQvz5WvyOw79II4i6DRaL +JA4KN/5aNYcCgYEA4EAqYNY2UGR0lqZtGTKdpmyp8nM/JRh2EJrqtbotJvnC/6hZ +/3LCteQftXVPm7AzzRSa1K/etZwUDqSlC7Y8ja4UEarCI/JN+qLNB2r80hU3o0hv +4NR2TbHknKl531q6pjybvk/erGefiVAeTqOP6UrTJURU0VIyfi/rtckDDckCgYBQ +Lm0/mrLtmw/gjCUCmObtnG5xH5y172lENgh67dYjFXi/Dn2YQe1+jASbRNsZLITl +T7N6LLYAeCR4cOVGkK80NCVg0U+c8xVVXeazXqG8ib0hZF/MujLhtD7O7uHlzzA1 +xd5+mzOqJeDC9Y+xhn+GQSM700Kilxjpkp1Ea370AwKBgGQzCY1tbO48s8RKd/Nz +oKG6ctp9S9vYtinXwuCdw0iL2i671bUgMONoXDNGcVBsYsuXb2324BKpw/bQK+BP +8p3TlBB1szA/W0EeueJkTHCkQninGc9vzvc6VbfacqJnuz7Pv/v1CkMa/E+ILamd +0aJoZHwNLuCkrzbVG+t+5yAS +-----END PRIVATE KEY----- -- 2.7.4 From 50e899abcb077f15bd7e72bd0a0ce2d934fb76db Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Fri, 13 May 2016 12:31:01 +0200 Subject: [PATCH 08/16] Prevent use of uninitialized variable in examples Change-Id: I79052b160cd3d009fe89652a33e0450ee1e516d3 --- examples/misc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/misc.c b/examples/misc.c index b3a8fdc..ef8c53c 100644 --- a/examples/misc.c +++ b/examples/misc.c @@ -54,7 +54,7 @@ int read_file(const char *path, char **data, size_t *data_len) int ret; char tmp[BUF_SIZE]; char *buf = NULL; - size_t buf_len; + size_t buf_len = 0; FILE *f; f = fopen(path, "r"); @@ -71,7 +71,6 @@ int read_file(const char *path, char **data, size_t *data_len) ret = -1; break; } - buf_len = 0; } else { char *new_buf = yaca_realloc(buf, buf_len + read); if (new_buf == NULL) { -- 2.7.4 From cd27fc8c0d7d36de901313c87efce3eee06e1c8b Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Fri, 13 May 2016 12:26:03 +0200 Subject: [PATCH 09/16] Remove symbol names from @brief paragraph Symbol names are not necessary in @brief paragraph. The symbol names are produced anyway and there's no point in duplicating them. Change-Id: I5283771962966cf2ff5ffbf91499f0c2fe8e48cd --- api/yaca/crypto.h | 41 ++++++++++++++++++++--------------------- api/yaca/digest.h | 6 +++--- api/yaca/encrypt.h | 14 +++++++------- api/yaca/error.h | 9 ++++----- api/yaca/key.h | 19 +++++++++---------- api/yaca/seal.h | 12 ++++++------ api/yaca/sign.h | 12 ++++++------ api/yaca/simple.h | 6 +++--- 8 files changed, 58 insertions(+), 61 deletions(-) diff --git a/api/yaca/crypto.h b/api/yaca/crypto.h index 52c7a32..20b444a 100644 --- a/api/yaca/crypto.h +++ b/api/yaca/crypto.h @@ -40,12 +40,12 @@ extern "C" { */ /** - * @brief YACA_CTX_NULL NULL value for the crypto context. + * @brief NULL value for the crypto context. */ #define YACA_CTX_NULL ((yaca_ctx_h) NULL) /** - * @brief yaca_init Initializes the library. Must be called before any other crypto function. + * @brief Initializes the library. Must be called before any other crypto function. * * @return 0 on success, negative on error. * @see yaca_exit() @@ -53,14 +53,14 @@ extern "C" { int yaca_init(void); /** - * @brief yaca_exit Closes the library. Must be called before exiting the application. + * @brief Closes the library. Must be called before exiting the application. * * @see yaca_init() */ void yaca_exit(void); /** - * @brief yaca_malloc Allocates the memory. + * @brief Allocates the memory. * * @param[in] size Size of the allocation (bytes). * @@ -71,7 +71,7 @@ void yaca_exit(void); void *yaca_malloc(size_t size); /** - * @brief yaca_zalloc Allocates the zeroed memory. + * @brief Allocates the zeroed memory. * * @param[in] size Size of the allocation (bytes). * @@ -82,7 +82,7 @@ void *yaca_malloc(size_t size); void *yaca_zalloc(size_t size); /** - * @brief yaca_realloc Re-allocates the memory. + * @brief Re-allocates the memory. * * @param[in] addr Address of the memory to be reallocated. * @param[in] size Size of the new allocation (bytes). @@ -94,8 +94,8 @@ void *yaca_zalloc(size_t size); void *yaca_realloc(void *addr, size_t size); /** - * @brief yaca_free Frees the memory allocated by yaca_malloc(), yaca_zalloc(), - * yaca_realloc() or one of the cryptographic operations. + * @brief 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() @@ -105,7 +105,7 @@ void *yaca_realloc(void *addr, size_t size); void yaca_free(void *ptr); /** - * @brief yaca_rand_bytes Generates random data. + * @brief Generates random data. * * @param[in,out] data Pointer to the memory to be randomized. * @param[in] data_len Length of the memory to be randomized. @@ -115,8 +115,8 @@ void yaca_free(void *ptr); int yaca_rand_bytes(char *data, size_t data_len); /** - * @brief yaca_ctx_set_param Sets the extended context parameters. - * Can only be called on an initialized context. + * @brief Sets the extended context parameters. Can only be called on an + * initialized context. * * @param[in,out] ctx Previously initialized crypto context. * @param[in] param Parameter to be set. @@ -132,8 +132,8 @@ int yaca_ctx_set_param(yaca_ctx_h ctx, size_t value_len); /** - * @brief yaca_ctx_get_param Returns the extended context parameters. - * Can only be called on an initialized context. + * @brief Returns the extended context parameters. Can only be called on an + * initialized context. * * @param[in] ctx Previously initialized crypto context. * @param[in] param Parameter to be read. @@ -149,9 +149,8 @@ int yaca_ctx_get_param(const yaca_ctx_h ctx, size_t *value_len); /** - * @brief yaca_ctx_free Destroys the crypto context. Must be called - * on all contexts that are no longer used. - * Passing YACA_CTX_NULL is allowed. + * @brief Destroys the crypto context. Must be called on all contexts that are + * no longer used. Passing YACA_CTX_NULL is allowed. * * @param[in,out] ctx Crypto context. * @see #yaca_ctx_h @@ -160,8 +159,8 @@ int yaca_ctx_get_param(const yaca_ctx_h ctx, void yaca_ctx_free(yaca_ctx_h ctx); /** - * @brief yaca_get_output_length Returns the output length for a given algorithm. - * Can only be called on an initialized context. + * @brief Returns the output length for a given algorithm. Can only be called + * on an initialized context. * * @param[in] ctx Previously initialized crypto context. * @param[in] input_len Length of the input data to be processed. @@ -173,17 +172,17 @@ void yaca_ctx_free(yaca_ctx_h ctx); int yaca_get_output_length(const yaca_ctx_h ctx, size_t input_len); /** - * @brief yaca_get_digest_length Wrapper - returns the length of the digest (for a given context). + * @brief Wrapper - returns the length of the digest (for a given context). */ #define yaca_get_digest_length(ctxa) yaca_get_output_length((ctxa), 0) /** - * @brief yaca_get_sign_length Wrapper - returns the length of the signature (for a given context). + * @brief Wrapper - returns the length of the signature (for a given context). */ #define yaca_get_sign_length(ctxa) yaca_get_output_length((ctxa), 0) /** - * @brief yaca_get_block_length Wrapper - returns the length of the block (for a given context). + * @brief Wrapper - returns the length of the block (for a given context). */ #define yaca_get_block_length(ctxa) yaca_get_output_length((ctxa), 0) diff --git a/api/yaca/digest.h b/api/yaca/digest.h index dc49b92..0ea17d4 100644 --- a/api/yaca/digest.h +++ b/api/yaca/digest.h @@ -40,7 +40,7 @@ extern "C" { */ /** - * @brief yaca_digest_init Initializes a digest context. + * @brief Initializes a digest context. * * @param[out] ctx Newly created context (must be freed with yaca_ctx_free()). * @param[in] algo Digest algorithm that will be used. @@ -51,7 +51,7 @@ extern "C" { 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. + * @brief Feeds the data into the message digest algorithm. * * @param[in,out] ctx Context created by yaca_digest_init(). * @param[in] data Data from which the digest is to be calculated. @@ -63,7 +63,7 @@ int yaca_digest_init(yaca_ctx_h *ctx, yaca_digest_algo_e algo); int yaca_digest_update(yaca_ctx_h ctx, const char *data, size_t data_len); /** - * @brief yaca_digest_final Calculates the final digest. + * @brief 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, diff --git a/api/yaca/encrypt.h b/api/yaca/encrypt.h index b62541d..23351cf 100644 --- a/api/yaca/encrypt.h +++ b/api/yaca/encrypt.h @@ -42,7 +42,7 @@ extern "C" { */ /** - * @brief yaca_encrypt_init Initializes an encryption context. + * @brief Initializes an encryption context. * * @param[out] ctx Newly created context (must be freed with yaca_ctx_free()). * @param[in] algo Encryption algorithm that will be used. @@ -60,7 +60,7 @@ int yaca_encrypt_init(yaca_ctx_h *ctx, const yaca_key_h iv); /** - * @brief yaca_encrypt_update Encrypts chunk of the data. + * @brief Encrypts chunk of the data. * * @param[in,out] ctx Context created by yaca_encrypt_init(). * @param[in] plain Plain text to be encrypted. @@ -79,7 +79,7 @@ int yaca_encrypt_update(yaca_ctx_h ctx, size_t *cipher_len); /** - * @brief yaca_encrypt_final Encrypts the final chunk of the data. + * @brief 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 @@ -94,7 +94,7 @@ int yaca_encrypt_final(yaca_ctx_h ctx, size_t *cipher_len); /** - * @brief yaca_decrypt_init Initializes an decryption context. + * @brief Initializes an decryption context. * * @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. @@ -112,7 +112,7 @@ int yaca_decrypt_init(yaca_ctx_h *ctx, const yaca_key_h iv); /** - * @brief yaca_decrypt_update Decrypts chunk of the data. + * @brief Decrypts chunk of the data. * * @param[in,out] ctx Context created by yaca_decrypt_init(). * @param[in] cipher Cipher text to be decrypted. @@ -131,7 +131,7 @@ int yaca_decrypt_update(yaca_ctx_h ctx, size_t *plain_len); /** - * @brief yaca_decrypt_final Decrypts the final chunk of the data. + * @brief 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 @@ -146,7 +146,7 @@ int yaca_decrypt_final(yaca_ctx_h ctx, size_t *plain_len); /** - * @brief yaca_get_iv_bits Returns the recomended/default length of the IV for a given encryption configuration. + * @brief Returns the recomended/default length of the IV for a given encryption configuration. * * @param[in] algo Encryption algorithm. * @param[in] bcm Chain mode. diff --git a/api/yaca/error.h b/api/yaca/error.h index 944d8a3..15addf0 100644 --- a/api/yaca/error.h +++ b/api/yaca/error.h @@ -54,12 +54,11 @@ enum __yaca_error_code { typedef void (*yaca_debug_func)(const char*); /** - * @brief yaca_error_set_debug_func Sets a current thread debug callback that will be called each - * time an internal error occurs. A NULL terminated string with - * location and description of the error will be passed as an - * argument. + * @brief Sets a current thread debug callback that will be called each time an + * internal error occurs. A NULL terminated string with location and + * description of the error will be passed as an argument. * - * @param[in] fn Function to set as internal error callback. + * @param[in] fn Function to set as internal error callback. */ void yaca_error_set_debug_func(yaca_debug_func fn); diff --git a/api/yaca/key.h b/api/yaca/key.h index 0ffc8cf..f97d6df 100644 --- a/api/yaca/key.h +++ b/api/yaca/key.h @@ -44,7 +44,7 @@ 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_bits Get key's length (in bits). + * @brief Get key's length (in bits). * * @param[in] key Key which length we return. * @@ -53,7 +53,7 @@ extern "C" { int yaca_key_get_bits(const yaca_key_h key); /** - * @brief yaca_key_import Imports a key. + * @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. @@ -81,7 +81,7 @@ int yaca_key_import(yaca_key_h *key, size_t data_len); /** - * @brief yaca_key_export Exports a key to arbitrary format. Export may fail if key is HW-based. + * @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. * @@ -113,7 +113,7 @@ int yaca_key_export(const yaca_key_h key, size_t *data_len); /** - * @brief yaca_key_gen Generates a secure key (or an initialization vector). + * @brief Generates a secure key (or an initialization vector). * * This function is used to generate symmetric and private asymmetric keys. * @@ -129,7 +129,7 @@ int yaca_key_gen(yaca_key_h *key, size_t key_bits); /** - * @brief yaca_key_extract_public Extracts public key from a private one. + * @brief Extracts public key from a private one. * * @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()). @@ -140,8 +140,7 @@ int yaca_key_gen(yaca_key_h *key, int yaca_key_extract_public(const yaca_key_h prv_key, yaca_key_h *pub_key); /** - * @brief yaca_key_free Frees the key created by the library. - * Passing YACA_KEY_NULL is allowed. + * @brief 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() @@ -161,7 +160,7 @@ void yaca_key_free(yaca_key_h key); */ /** - * @brief yaca_key_derive_dh Derives a key using Diffie-Helmann or EC Diffie-Helmann key exchange protocol. + * @brief Derives a key using Diffie-Helmann or EC Diffie-Helmann key exchange protocol. * * @param[in] prv_key Our private key. * @param[in] pub_key Peer public key. @@ -175,7 +174,7 @@ int yaca_key_derive_dh(const yaca_key_h prv_key, yaca_key_h *sym_key); /** - * @brief yaca_key_derive_kea Derives a key using KEA key exchange protocol. + * @brief Derives a key using KEA key exchange protocol. * * @param[in] prv_key Our DH private component. * @param[in] pub_key Peers' DH public component. @@ -195,7 +194,7 @@ int yaca_key_derive_kea(const yaca_key_h prv_key, yaca_key_h *sym_key); /** - * @brief yaca_key_derive_pbkdf2 Derives a key from user password (PKCS #5 a.k.a. pbkdf2 algorithm). + * @brief Derives a key from user password (PKCS #5 a.k.a. pbkdf2 algorithm). * * @param[in] password User password as a NULL-terminated string. * @param[in] salt Salt, should be non-zero. diff --git a/api/yaca/seal.h b/api/yaca/seal.h index a6897be..4786ebe 100644 --- a/api/yaca/seal.h +++ b/api/yaca/seal.h @@ -44,7 +44,7 @@ extern "C" { */ /** - * @brief yaca_seal_init Initializes an asymmetric encryption context. + * @brief Initializes an asymmetric encryption context. * * @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. @@ -66,7 +66,7 @@ int yaca_seal_init(yaca_ctx_h *ctx, yaca_key_h *iv); /** - * @brief yaca_seal_update Encrypts piece of the data. + * @brief Encrypts piece of the data. * * @param[in,out] ctx Context created by yaca_seal_init(). * @param[in] plain Plain text to be encrypted. @@ -85,7 +85,7 @@ int yaca_seal_update(yaca_ctx_h ctx, size_t *cipher_len); /** - * @brief yaca_seal_final Encrypts the final piece of the data. + * @brief 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 @@ -100,7 +100,7 @@ int yaca_seal_final(yaca_ctx_h ctx, size_t *cipher_len); /** - * @brief yaca_open_init Initializes an asymmetric decryption context. + * @brief Initializes an asymmetric decryption context. * * @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. @@ -122,7 +122,7 @@ int yaca_open_init(yaca_ctx_h *ctx, const yaca_key_h iv); /** - * @brief yaca_open_update Decrypts piece of the data. + * @brief Decrypts piece of the data. * * @param[in,out] ctx Context created by yaca_open_init(). * @param[in] cipher Cipher text to be decrypted. @@ -141,7 +141,7 @@ int yaca_open_update(yaca_ctx_h ctx, size_t *plain_len); /** - * @brief yaca_open_final Decrypts last chunk of sealed message. + * @brief 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 diff --git a/api/yaca/sign.h b/api/yaca/sign.h index 91c47d1..a5feb21 100644 --- a/api/yaca/sign.h +++ b/api/yaca/sign.h @@ -41,7 +41,7 @@ extern "C" { */ /** - * @brief yaca_sign_init Initializes a signature context. + * @brief Initializes a signature context. * * @param[out] ctx Newly created context (must be freed with yaca_ctx_free()). * @param[in] algo Digest algorithm that will be used. @@ -55,7 +55,7 @@ int yaca_sign_init(yaca_ctx_h *ctx, const yaca_key_h key); /** - * @brief yaca_sign_update Feeds the data into the digital signature algorithm. + * @brief Feeds the data into the digital signature algorithm. * * @param[in,out] ctx Context created by yaca_sign_init(). * @param[in] data Data to be signed. @@ -69,7 +69,7 @@ int yaca_sign_update(yaca_ctx_h ctx, size_t data_len); /** - * @brief yaca_sign_final Calculates the final signature. + * @brief 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 @@ -84,7 +84,7 @@ int yaca_sign_final(yaca_ctx_h ctx, size_t *mac_len); /** - * @brief yaca_verify_init Initializes a signature verification context. + * @brief Initializes a signature verification context. * * @param[out] ctx Newly created context (must be freed with yaca_ctx_free()). * @param[in] algo Digest algorithm that will be used. @@ -98,7 +98,7 @@ int yaca_verify_init(yaca_ctx_h *ctx, const yaca_key_h key); /** - * @brief yaca_verify_update Feeds the data into the digital signature verification algorithm. + * @brief Feeds the data into the digital signature verification algorithm. * * @param[in,out] ctx Context created by yaca_verify_init(). * @param[in] data Data to be verified. @@ -112,7 +112,7 @@ int yaca_verify_update(yaca_ctx_h ctx, size_t data_len); /** - * @brief yaca_verify_final Performs the verification. + * @brief Performs the verification. * * @param[in,out] ctx A valid verify context. * @param[in] mac Input MAC or signature (returned by yaca_sign_final()). diff --git a/api/yaca/simple.h b/api/yaca/simple.h index 3075aac..42a7545 100644 --- a/api/yaca/simple.h +++ b/api/yaca/simple.h @@ -48,7 +48,7 @@ extern "C" { */ /** - * @brief yaca_digest_calc Calculate a digest of a buffer. + * @brief Calculate a digest of a buffer. * * @param[in] algo Digest algorithm (select #YACA_DIGEST_SHA256 if unsure). * @param[in] data Data from which the digest is to be calculated. @@ -67,7 +67,7 @@ int yaca_digest_calc(yaca_digest_algo_e algo, size_t *digest_len); /** - * @brief yaca_encrypt Encrypt data using a symmetric cipher. + * @brief Encrypt data using a symmetric cipher. * * @param[in] algo Encryption algorithm (select #YACA_ENC_AES if unsure). * @param[in] bcm Chaining mode (select #YACA_BCM_CBC if unsure). @@ -92,7 +92,7 @@ int yaca_encrypt(yaca_enc_algo_e algo, size_t *cipher_len); /** - * @brief yaca_decrypt Decrypta data using a symmetric cipher. + * @brief Decrypt 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. -- 2.7.4 From 9f6b51792eae7e4ae5712c9d8f7efca8c9184115 Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Fri, 13 May 2016 12:45:55 +0200 Subject: [PATCH 10/16] Add prefix to header guards to avoid conflicts. Change-Id: I1e96b8ca538d61da8d4ae34ab9ee632472e192ce --- api/yaca/crypto.h | 6 +++--- api/yaca/digest.h | 6 +++--- api/yaca/encrypt.h | 6 +++--- api/yaca/error.h | 6 +++--- api/yaca/key.h | 6 +++--- api/yaca/seal.h | 6 +++--- api/yaca/sign.h | 6 +++--- api/yaca/simple.h | 6 +++--- api/yaca/types.h | 6 +++--- src/internal.h | 6 +++--- 10 files changed, 30 insertions(+), 30 deletions(-) diff --git a/api/yaca/crypto.h b/api/yaca/crypto.h index 20b444a..205cce2 100644 --- a/api/yaca/crypto.h +++ b/api/yaca/crypto.h @@ -21,8 +21,8 @@ * @brief */ -#ifndef CRYPTO_H -#define CRYPTO_H +#ifndef YACA_CRYPTO_H +#define YACA_CRYPTO_H #include #include @@ -192,4 +192,4 @@ int yaca_get_output_length(const yaca_ctx_h ctx, size_t input_len); } /* extern */ #endif -#endif /* CRYPTO_H */ +#endif /* YACA_CRYPTO_H */ diff --git a/api/yaca/digest.h b/api/yaca/digest.h index 0ea17d4..5e3aa0d 100644 --- a/api/yaca/digest.h +++ b/api/yaca/digest.h @@ -21,8 +21,8 @@ * @brief */ -#ifndef DIGEST_H -#define DIGEST_H +#ifndef YACA_DIGEST_H +#define YACA_DIGEST_H #include #include @@ -81,4 +81,4 @@ int yaca_digest_final(yaca_ctx_h ctx, char *digest, size_t *digest_len); } /* extern */ #endif -#endif /* DIGEST_H */ +#endif /* YACA_DIGEST_H */ diff --git a/api/yaca/encrypt.h b/api/yaca/encrypt.h index 23351cf..7806e16 100644 --- a/api/yaca/encrypt.h +++ b/api/yaca/encrypt.h @@ -21,8 +21,8 @@ * @brief */ -#ifndef ENCRYPT_H -#define ENCRYPT_H +#ifndef YACA_ENCRYPT_H +#define YACA_ENCRYPT_H #include #include @@ -164,4 +164,4 @@ int yaca_get_iv_bits(yaca_enc_algo_e algo, } /* extern */ #endif -#endif /* ENCRYPT_H */ +#endif /* YACA_ENCRYPT_H */ diff --git a/api/yaca/error.h b/api/yaca/error.h index 15addf0..55656bd 100644 --- a/api/yaca/error.h +++ b/api/yaca/error.h @@ -21,8 +21,8 @@ * @brief */ -#ifndef ERROR_H -#define ERROR_H +#ifndef YACA_ERROR_H +#define YACA_ERROR_H #ifdef __cplusplus extern "C" { @@ -68,4 +68,4 @@ void yaca_error_set_debug_func(yaca_debug_func fn); } /* extern */ #endif -#endif /* ERROR_H */ +#endif /* YACA_ERROR_H */ diff --git a/api/yaca/key.h b/api/yaca/key.h index f97d6df..ce69f21 100644 --- a/api/yaca/key.h +++ b/api/yaca/key.h @@ -21,8 +21,8 @@ * @brief */ -#ifndef KEY_H -#define KEY_H +#ifndef YACA_KEY_H +#define YACA_KEY_H #include #include @@ -224,4 +224,4 @@ int yaca_key_derive_pbkdf2(const char *password, } /* extern */ #endif -#endif /* KEY_H */ +#endif /* YACA_KEY_H */ diff --git a/api/yaca/seal.h b/api/yaca/seal.h index 4786ebe..4f7b2fa 100644 --- a/api/yaca/seal.h +++ b/api/yaca/seal.h @@ -21,8 +21,8 @@ * @brief */ -#ifndef SEAL_H -#define SEAL_H +#ifndef YACA_SEAL_H +#define YACA_SEAL_H #include #include @@ -161,4 +161,4 @@ int yaca_open_final(yaca_ctx_h ctx, } /* extern */ #endif -#endif /* SEAL_H */ +#endif /* YACA_SEAL_H */ diff --git a/api/yaca/sign.h b/api/yaca/sign.h index a5feb21..f018a31 100644 --- a/api/yaca/sign.h +++ b/api/yaca/sign.h @@ -21,8 +21,8 @@ * @brief */ -#ifndef SIGN_H -#define SIGN_H +#ifndef YACA_SIGN_H +#define YACA_SIGN_H #include #include @@ -131,4 +131,4 @@ int yaca_verify_final(yaca_ctx_h ctx, } /* extern */ #endif -#endif /* SIGN_H */ +#endif /* YACA_SIGN_H */ diff --git a/api/yaca/simple.h b/api/yaca/simple.h index 42a7545..ec1e333 100644 --- a/api/yaca/simple.h +++ b/api/yaca/simple.h @@ -21,8 +21,8 @@ * @brief */ -#ifndef SIMPLE_H -#define SIMPLE_H +#ifndef YACA_SIMPLE_H +#define YACA_SIMPLE_H #include #include @@ -124,4 +124,4 @@ int yaca_decrypt(yaca_enc_algo_e algo, } /* extern */ #endif -#endif /* SIMPLE_H */ +#endif /* YACA_SIMPLE_H */ diff --git a/api/yaca/types.h b/api/yaca/types.h index ea9b2bd..d069fc2 100644 --- a/api/yaca/types.h +++ b/api/yaca/types.h @@ -21,8 +21,8 @@ * @brief */ -#ifndef TYPES_H -#define TYPES_H +#ifndef YACA_TYPES_H +#define YACA_TYPES_H #ifdef __cplusplus extern "C" { @@ -289,4 +289,4 @@ typedef enum { } /* extern */ #endif -#endif /* TYPES_H */ +#endif /* YACA_TYPES_H */ diff --git a/src/internal.h b/src/internal.h index 119728f..5d1f49a 100644 --- a/src/internal.h +++ b/src/internal.h @@ -21,8 +21,8 @@ * @brief Internal API */ -#ifndef INTERNAL_H -#define INTERNAL_H +#ifndef YACA_INTERNAL_H +#define YACA_INTERNAL_H #include #include @@ -103,4 +103,4 @@ 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)) -#endif +#endif /* YACA_INTERNAL_H */ -- 2.7.4 From f27c652d044cee5cd386904ac9f70cd545b62833 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Mon, 9 May 2016 16:27:22 +0200 Subject: [PATCH 11/16] Generate/import/export DES key. Change-Id: Iac23685e9be18204c0d9a317bf4aa17e4539e556 --- api/yaca/types.h | 3 +-- src/key.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 72 insertions(+), 6 deletions(-) diff --git a/api/yaca/types.h b/api/yaca/types.h index d069fc2..5b8c6b6 100644 --- a/api/yaca/types.h +++ b/api/yaca/types.h @@ -101,9 +101,8 @@ typedef enum { YACA_KEY_CURVE_P256 = 256, /**< ECC: P-256 curve */ YACA_KEY_CURVE_P384 = 384, /**< ECC: SECP-384 curve */ YACA_KEY_UNSAFE_40BIT = 40, - YACA_KEY_UNSAFE_56BIT = 56, + YACA_KEY_UNSAFE_64BIT = 64, YACA_KEY_UNSAFE_80BIT = 80, - YACA_KEY_UNSAFE_112BIT = 112, YACA_KEY_UNSAFE_128BIT = 128, YACA_KEY_192BIT = 192, YACA_KEY_256BIT = 256, diff --git a/src/key.c b/src/key.c index db8b6c4..bb6bc32 100644 --- a/src/key.c +++ b/src/key.c @@ -23,8 +23,6 @@ #include #include -#include - #include #include #include @@ -34,6 +32,7 @@ #include #include #include +#include #include "internal.h" @@ -194,6 +193,17 @@ int import_simple(yaca_key_h *key, goto out; } + /* DES key length verification */ + if (key_type == YACA_KEY_TYPE_DES) { + size_t key_bits = key_data_len * 8; + if (key_bits != YACA_KEY_UNSAFE_64BIT && + key_bits != YACA_KEY_UNSAFE_128BIT && + key_bits != YACA_KEY_192BIT) { + ret = YACA_ERROR_INVALID_ARGUMENT; + goto out; + } + } + nk = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_data_len); if (nk == NULL) { ret = YACA_ERROR_OUT_OF_MEMORY; @@ -575,6 +585,54 @@ int gen_simple(struct yaca_key_simple_s **out, size_t key_bits) return 0; } +int gen_simple_des(struct yaca_key_simple_s **out, size_t key_bits) +{ + assert(out != NULL); + + if (key_bits != YACA_KEY_UNSAFE_64BIT && + key_bits != YACA_KEY_UNSAFE_128BIT && + key_bits != YACA_KEY_192BIT) + return YACA_ERROR_INVALID_ARGUMENT; + + int ret; + struct yaca_key_simple_s *nk; + size_t key_byte_len = key_bits / 8; + + if (key_byte_len > SIZE_MAX - sizeof(struct yaca_key_simple_s)) + return YACA_ERROR_TOO_BIG_ARGUMENT; + + nk = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_byte_len); + if (nk == NULL) + return YACA_ERROR_OUT_OF_MEMORY; + + DES_cblock *des_key = (DES_cblock*)nk->d; + if (key_byte_len >= 8) { + ret = DES_random_key(des_key); + if (ret != 1) + goto free_nk; + } + if (key_byte_len >= 16) { + ret = DES_random_key(des_key + 1); + if (ret != 1) + goto free_nk; + } + if (key_byte_len >= 24) { + ret = DES_random_key(des_key + 2); + if (ret != 1) + goto free_nk; + } + + nk->bits = key_bits; + *out = nk; + return 0; + +free_nk: + yaca_free(nk); + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + return ret; +} + int gen_evp_rsa(struct yaca_key_evp_s **out, size_t key_bits) { assert(out != NULL); @@ -800,6 +858,7 @@ API int yaca_key_import(yaca_key_h *key, switch (key_type) { case YACA_KEY_TYPE_SYMMETRIC: + case YACA_KEY_TYPE_DES: case YACA_KEY_TYPE_IV: return import_simple(key, key_type, data, data_len); case YACA_KEY_TYPE_RSA_PUB: @@ -807,7 +866,6 @@ API int yaca_key_import(yaca_key_h *key, case YACA_KEY_TYPE_DSA_PUB: case YACA_KEY_TYPE_DSA_PRIV: return import_evp(key, key_type, data, data_len); - case YACA_KEY_TYPE_DES: case YACA_KEY_TYPE_DH_PUB: case YACA_KEY_TYPE_DH_PRIV: case YACA_KEY_TYPE_ECDSA_PUB: @@ -878,6 +936,16 @@ API int yaca_key_gen(yaca_key_h *key, *key = (yaca_key_h)nk_simple; return 0; + case YACA_KEY_TYPE_DES: + ret = gen_simple_des(&nk_simple, key_bits); + if (ret != 0) + return ret; + + nk_simple->key.type = key_type; + + *key = (yaca_key_h)nk_simple; + return 0; + case YACA_KEY_TYPE_RSA_PRIV: ret = gen_evp_rsa(&nk_evp, key_bits); if (ret != 0) @@ -898,7 +966,6 @@ API int yaca_key_gen(yaca_key_h *key, *key = (yaca_key_h)nk_evp; return 0; - case YACA_KEY_TYPE_DES: case YACA_KEY_TYPE_DH_PRIV: case YACA_KEY_TYPE_ECDSA_PRIV: case YACA_KEY_TYPE_ECDH_PRIV: -- 2.7.4 From 04b77abf66cf36be5b411d81311918ea6f59d83d Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Mon, 9 May 2016 16:30:23 +0200 Subject: [PATCH 12/16] Add support to DES encrypt/decrypt. Update documentation. Change-Id: Ide2d1f93cd2deef711a7fdfd2dd922f46f8f3637 --- api/yaca/types.h | 22 ++++++++++++++++++--- src/encrypt.c | 60 +++++++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 63 insertions(+), 19 deletions(-) diff --git a/api/yaca/types.h b/api/yaca/types.h index 5b8c6b6..4363932 100644 --- a/api/yaca/types.h +++ b/api/yaca/types.h @@ -139,24 +139,40 @@ typedef enum { /** * DES encryption. + * - Supported key lengths: @c 64. + * - Supported block cipher modes: + * #YACA_BCM_CBC, + * #YACA_BCM_OFB, + * #YACA_BCM_CFB, + * #YACA_BCM_ECB * - 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. + * - Supported key lengths: @c 128. + * - Supported block cipher modes: + * #YACA_BCM_CBC, + * #YACA_BCM_OFB, + * #YACA_BCM_CFB, + * #YACA_BCM_ECB * - 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. + * - Supported key lengths: @c 192. + * - Supported block cipher modes: + * #YACA_BCM_CBC, + * #YACA_BCM_OFB, + * #YACA_BCM_CFB, + * #YACA_BCM_ECB * - 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, diff --git a/src/encrypt.c b/src/encrypt.c index 40aa2ee..ad2334b 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -95,6 +95,10 @@ static const char *encrypt_algo_to_str(yaca_enc_algo_e algo) return "aes"; case YACA_ENC_UNSAFE_DES: return "des"; + case YACA_ENC_UNSAFE_3DES_2TDEA: + return "des-ede"; + case YACA_ENC_3DES_3TDEA: + return "des-ede3"; case YACA_ENC_UNSAFE_RC2: return "rc2"; case YACA_ENC_UNSAFE_RC4: @@ -102,8 +106,6 @@ static const char *encrypt_algo_to_str(yaca_enc_algo_e algo) case YACA_ENC_CAST5: return "cast5"; - case YACA_ENC_UNSAFE_3DES_2TDEA: // TODO: add 3des/2tdea support - case YACA_ENC_3DES_3TDEA: // TODO: add 3des/3tdea support case YACA_ENC_UNSAFE_SKIPJACK: // TODO: add skipjack implementation default: return NULL; @@ -149,8 +151,32 @@ int encrypt_get_algorithm(yaca_enc_algo_e algo, cipher == NULL) return YACA_ERROR_INVALID_ARGUMENT; - ret = snprintf(cipher_name, sizeof(cipher_name), "%s-%zu-%s", algo_name, - key_bits, bcm_name); + switch(algo) + { + case YACA_ENC_AES: + ret = snprintf(cipher_name, sizeof(cipher_name), "%s-%zu-%s", + algo_name, key_bits, bcm_name); + break; + case YACA_ENC_UNSAFE_DES: + ret = snprintf(cipher_name, sizeof(cipher_name), "%s-%s", + algo_name, bcm_name); + break; + case YACA_ENC_UNSAFE_3DES_2TDEA: + case YACA_ENC_3DES_3TDEA: + if (bcm == YACA_BCM_ECB) + ret = snprintf(cipher_name, sizeof(cipher_name), "%s", algo_name); + else + ret = snprintf(cipher_name, sizeof(cipher_name), "%s-%s", + algo_name, bcm_name); + break; + case YACA_ENC_UNSAFE_RC2: + case YACA_ENC_UNSAFE_RC4: + case YACA_ENC_CAST5: + case YACA_ENC_UNSAFE_SKIPJACK: + default: + return YACA_ERROR_NOT_IMPLEMENTED; + } + if (ret < 0) return YACA_ERROR_INVALID_ARGUMENT; if ((unsigned)ret >= sizeof(cipher_name)) // output was truncated @@ -179,6 +205,7 @@ static int encrypt_init(yaca_ctx_h *ctx, struct yaca_encrypt_ctx_s *nc; const EVP_CIPHER *cipher; int key_bits; + unsigned char *iv_data = NULL; int iv_bits; int ret; @@ -221,16 +248,17 @@ static int encrypt_init(yaca_ctx_h *ctx, goto err_free; } - liv = key_get_simple(iv); - if (ret != 0 && liv == NULL) { /* cipher requires iv, but none was provided */ - 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; + if (iv_bits != 0) { /* cipher requires iv*/ + liv = key_get_simple(iv); + if (liv == NULL) { /* iv was not provided */ + ret = YACA_ERROR_INVALID_ARGUMENT; + goto err_free; + } + if (iv_bits != yaca_key_get_bits(iv)) { /* IV length doesn't match cipher */ + ret = YACA_ERROR_INVALID_ARGUMENT; + goto err_free; + } + iv_data = (unsigned char*)liv->d; } nc->cipher_ctx = EVP_CIPHER_CTX_new(); @@ -244,12 +272,12 @@ static int encrypt_init(yaca_ctx_h *ctx, case OP_ENCRYPT: ret = EVP_EncryptInit(nc->cipher_ctx, cipher, (unsigned char*)lkey->d, - (unsigned char*)liv->d); + iv_data); break; case OP_DECRYPT: ret = EVP_DecryptInit(nc->cipher_ctx, cipher, (unsigned char*)lkey->d, - (unsigned char*)liv->d); + iv_data); break; default: ret = YACA_ERROR_INVALID_ARGUMENT; -- 2.7.4 From 2837f2a23d0a01c428142c966ace8aeff78791e2 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Tue, 10 May 2016 14:57:30 +0200 Subject: [PATCH 13/16] Add support to CAST5 encrypt/decrypt. Update documentation. Change-Id: I645018182fc723190223eac627c665d84da41340 --- api/yaca/types.h | 9 +++++++-- src/encrypt.c | 42 +++++++++++++++++++++++++++++++++++------- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/api/yaca/types.h b/api/yaca/types.h index 4363932..3397e86 100644 --- a/api/yaca/types.h +++ b/api/yaca/types.h @@ -192,9 +192,14 @@ typedef enum { /** * CAST5 encryption. + * This is a variable key length cipher. + * Supported key lengths: 40-128 bits in steps of 8 bits. + * - Supported block cipher modes: + * #YACA_BCM_CBC, + * #YACA_BCM_OFB, + * #YACA_BCM_CFB, + * #YACA_BCM_ECB * - 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, diff --git a/src/encrypt.c b/src/encrypt.c index ad2334b..d185c16 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -172,6 +172,9 @@ int encrypt_get_algorithm(yaca_enc_algo_e algo, case YACA_ENC_UNSAFE_RC2: case YACA_ENC_UNSAFE_RC4: case YACA_ENC_CAST5: + ret = snprintf(cipher_name, sizeof(cipher_name), "%s-%s", + algo_name, bcm_name); + break; case YACA_ENC_UNSAFE_SKIPJACK: default: return YACA_ERROR_NOT_IMPLEMENTED; @@ -225,7 +228,6 @@ static int encrypt_init(yaca_ctx_h *ctx, nc->ctx.get_output_length = get_encrypt_output_length; nc->op_type = op_type; - // TODO: handling of algorithms with variable key length ret = yaca_key_get_bits(sym_key); if (ret < 0) goto err_free; @@ -270,14 +272,40 @@ static int encrypt_init(yaca_ctx_h *ctx, switch (op_type) { case OP_ENCRYPT: - ret = EVP_EncryptInit(nc->cipher_ctx, cipher, - (unsigned char*)lkey->d, - iv_data); + ret = EVP_EncryptInit_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_EncryptInit_ex(nc->cipher_ctx, NULL, NULL, + (unsigned char*)lkey->d, + iv_data); + break; case OP_DECRYPT: - ret = EVP_DecryptInit(nc->cipher_ctx, cipher, - (unsigned char*)lkey->d, - iv_data); + 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; -- 2.7.4 From 320235dd678e6425ef2e8117067ea6a93bca2c25 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Wed, 11 May 2016 09:31:30 +0200 Subject: [PATCH 14/16] [FIX] ECB mode does not use an IV, so IV can be YACA_KEY_NULL. Change-Id: I64dbb66346176da764009ffb549451fffa5a5435 --- src/simple.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/simple.c b/src/simple.c index ff7f19e..bb8eeec 100644 --- a/src/simple.c +++ b/src/simple.c @@ -94,7 +94,7 @@ API int yaca_encrypt(yaca_enc_algo_e algo, size_t out_len, lcipher_len, written; if (plain == NULL || plain_len == 0 || cipher == NULL || cipher_len == NULL || - sym_key == YACA_KEY_NULL || iv == YACA_KEY_NULL) + sym_key == YACA_KEY_NULL) return YACA_ERROR_INVALID_ARGUMENT; if (plain_len > INT_MAX) /* TODO: this is because get_output_length returns signed int - perhaps we should change that */ @@ -171,7 +171,7 @@ API int yaca_decrypt(yaca_enc_algo_e algo, size_t out_len, lplain_len, written; if (cipher == NULL || cipher_len == 0 || plain == NULL || plain_len == NULL || - sym_key == YACA_KEY_NULL || iv == YACA_KEY_NULL) + sym_key == YACA_KEY_NULL) return YACA_ERROR_INVALID_ARGUMENT; if (cipher_len > INT_MAX) /* TODO: this is because get_output_length returns signed int - perhaps we should change that */ -- 2.7.4 From 0cb7bca2390db4d2d1e3c0be1d15c2842ed276be Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Wed, 11 May 2016 11:04:43 +0200 Subject: [PATCH 15/16] Add support to RC2/RC4 encrypt/decrypt. Update documentation. Change-Id: I57a54e9581af12ffe73a721c7cae8c3880df94ab --- api/yaca/types.h | 35 +++++++++++++++++++++++++---------- src/encrypt.c | 9 +++++---- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/api/yaca/types.h b/api/yaca/types.h index 3397e86..7ce9ec9 100644 --- a/api/yaca/types.h +++ b/api/yaca/types.h @@ -100,6 +100,7 @@ typedef enum { YACA_KEY_CURVE_P192 = 192, /**< ECC: P192 curve */ YACA_KEY_CURVE_P256 = 256, /**< ECC: P-256 curve */ YACA_KEY_CURVE_P384 = 384, /**< ECC: SECP-384 curve */ + YACA_KEY_UNSAFE_8BIT = 8, YACA_KEY_UNSAFE_40BIT = 40, YACA_KEY_UNSAFE_64BIT = 64, YACA_KEY_UNSAFE_80BIT = 80, @@ -178,15 +179,23 @@ typedef enum { /** * RC2 encryption. - * - The key length is extracted from the key buffer. + * This is a variable key length cipher. * - Supported key lengths: 8-1024 bits in steps of 8 bits. + * - Additional parameter, effective key bits: #YACA_PARAM_RC2_EFFECTIVE_KEY_BITS, + * by default equals to 128 + * - Supported block cipher modes: + * #YACA_BCM_CBC, + * #YACA_BCM_OFB, + * #YACA_BCM_CFB, + * #YACA_BCM_ECB */ YACA_ENC_UNSAFE_RC2, /** * RC4 encryption. - * - The key length is extracted from the key buffer. + * This is a variable key length cipher. * - Supported key lengths: 40–2048 bits in steps of 8 bits. + * This cipher doesn't support block cipher modes, use #YACA_BCM_NONE instead. */ YACA_ENC_UNSAFE_RC4, @@ -215,6 +224,11 @@ typedef enum { */ typedef enum { /** + * Used when algorithm doesn't support block ciphers modes. + */ + YACA_BCM_NONE, + + /** * ECB block cipher mode. * Encrypts 64 bit at a time. No IV is used. */ @@ -277,17 +291,18 @@ typedef enum { * @brief Non-standard parameters for algorithms */ typedef enum { - YACA_PARAM_PADDING, /**< Padding */ + YACA_PARAM_PADDING, /**< Padding */ - YACA_PARAM_CTR_CNT, /**< CTR Counter bits */ + YACA_PARAM_RC2_EFFECTIVE_KEY_BITS, /**< RC2 effective key bits, 1-1024, 1 bit resolution */ + YACA_PARAM_CTR_CNT, /**< CTR Counter bits */ - YACA_PARAM_GCM_AAD, /**< GCM Additional Authentication Data */ - YACA_PARAM_GCM_TAG, /**< GCM Tag bits */ - YACA_PARAM_GCM_TAG_LEN, /**< GCM Tag length */ + YACA_PARAM_GCM_AAD, /**< GCM Additional Authentication Data */ + YACA_PARAM_GCM_TAG, /**< GCM Tag bits */ + YACA_PARAM_GCM_TAG_LEN, /**< GCM Tag length */ - YACA_PARAM_CCM_AAD, /**< CCM Additional Authentication Data */ - YACA_PARAM_CCM_TAG, /**< CCM Tag bits */ - YACA_PARAM_CCM_TAG_LEN, /**< CCM Tag length */ + YACA_PARAM_CCM_AAD, /**< CCM Additional Authentication Data */ + YACA_PARAM_CCM_TAG, /**< CCM Tag bits */ + YACA_PARAM_CCM_TAG_LEN, /**< CCM Tag length */ } yaca_ex_param_e; /** diff --git a/src/encrypt.c b/src/encrypt.c index d185c16..ec2176f 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -115,6 +115,8 @@ static const char *encrypt_algo_to_str(yaca_enc_algo_e algo) static const char *bcm_to_str(yaca_block_cipher_mode_e bcm) { switch (bcm) { + case YACA_BCM_NONE: + return "none"; case YACA_BCM_ECB: return "ecb"; case YACA_BCM_CBC: @@ -158,6 +160,8 @@ int encrypt_get_algorithm(yaca_enc_algo_e algo, algo_name, key_bits, bcm_name); break; case YACA_ENC_UNSAFE_DES: + case YACA_ENC_UNSAFE_RC2: + case YACA_ENC_CAST5: ret = snprintf(cipher_name, sizeof(cipher_name), "%s-%s", algo_name, bcm_name); break; @@ -169,11 +173,8 @@ int encrypt_get_algorithm(yaca_enc_algo_e algo, ret = snprintf(cipher_name, sizeof(cipher_name), "%s-%s", algo_name, bcm_name); break; - case YACA_ENC_UNSAFE_RC2: case YACA_ENC_UNSAFE_RC4: - case YACA_ENC_CAST5: - ret = snprintf(cipher_name, sizeof(cipher_name), "%s-%s", - algo_name, bcm_name); + ret = snprintf(cipher_name, sizeof(cipher_name), "%s", algo_name); break; case YACA_ENC_UNSAFE_SKIPJACK: default: -- 2.7.4 From 602946e72763a25f9ea4c19e43f3d3769836833d Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Fri, 13 May 2016 16:45:41 +0200 Subject: [PATCH 16/16] Fix API for get_output_length() Return the value by size_t param instead of signed int return. The return value is used only for error codes from now on. Change-Id: I8c4665342316f35d9aea1d2b3605a1248fc31b17 --- api/yaca/crypto.h | 15 +++++++-------- examples/digest.c | 5 ++--- examples/encrypt.c | 24 ++++++++---------------- examples/encrypt_aes_gcm.c | 31 ++++++++++++++++--------------- examples/seal.c | 8 ++++---- examples/sign.c | 6 +++--- src/crypto.c | 4 ++-- src/digest.c | 5 +++-- src/encrypt.c | 17 ++++++++++++----- src/internal.h | 2 +- src/seal.c | 15 +++++++++++---- src/sign.c | 5 +++-- src/simple.c | 42 +++++++++++++++++++++--------------------- 13 files changed, 93 insertions(+), 86 deletions(-) diff --git a/api/yaca/crypto.h b/api/yaca/crypto.h index 205cce2..ec6ac1b 100644 --- a/api/yaca/crypto.h +++ b/api/yaca/crypto.h @@ -162,29 +162,28 @@ 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. * - * @param[in] ctx Previously initialized crypto context. - * @param[in] input_len Length of the input data to be processed. + * @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. * * @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 -int yaca_get_output_length(const yaca_ctx_h ctx, size_t input_len); +int yaca_get_output_length(const yaca_ctx_h ctx, size_t input_len, size_t *output_len); /** * @brief Wrapper - returns the length of the digest (for a given context). */ -#define yaca_get_digest_length(ctxa) yaca_get_output_length((ctxa), 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). */ -#define yaca_get_sign_length(ctxa) yaca_get_output_length((ctxa), 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). */ -#define yaca_get_block_length(ctxa) yaca_get_output_length((ctxa), 0) +#define yaca_get_block_length(ctxa, output_len) yaca_get_output_length((ctxa), 0, (output_len)) /**@}*/ diff --git a/examples/digest.c b/examples/digest.c index 9ee0b41..a5ef093 100644 --- a/examples/digest.c +++ b/examples/digest.c @@ -59,10 +59,9 @@ void digest_advanced(void) if (ret < 0) goto exit_ctx; - // TODO: rename to yaca_digest_get_length?? size_t digest_len; - digest_len = yaca_get_digest_length(ctx); - if (digest_len <= 0) + ret = yaca_get_digest_length(ctx, &digest_len); + if (ret != 0) goto exit_ctx; { diff --git a/examples/encrypt.c b/examples/encrypt.c index 8615abe..6233f7b 100644 --- a/examples/encrypt.c +++ b/examples/encrypt.c @@ -134,18 +134,14 @@ void encrypt_advanced(void) if (ret) goto ex_iv; - ret = yaca_get_block_length(ctx); - if (ret < 0) + ret = yaca_get_block_length(ctx, &block_len); + if (ret != 0) goto ex_ctx; - block_len = ret; - - ret = yaca_get_output_length(ctx, LOREM4096_SIZE); - if (ret < 0) + ret = yaca_get_output_length(ctx, LOREM4096_SIZE, &output_len); + if (ret != 0) goto ex_ctx; - output_len = ret; - /* Calculate max output: size of update + final chunks */ enc_size = output_len + block_len; enc = yaca_malloc(enc_size); @@ -184,18 +180,14 @@ void encrypt_advanced(void) goto ex_of; } - ret = yaca_get_block_length(ctx); - if (ret < 0) + ret = yaca_get_block_length(ctx, &block_len); + if (ret != 0) goto ex_of; - block_len = ret; - - ret = yaca_get_output_length(ctx, LOREM4096_SIZE); - if (ret < 0) + ret = yaca_get_output_length(ctx, LOREM4096_SIZE, &output_len); + if (ret != 0) goto ex_ctx; - output_len = ret; - /* Calculate max output: size of update + final chunks */ dec_size = output_len + block_len; dec = yaca_malloc(dec_size); diff --git a/examples/encrypt_aes_gcm.c b/examples/encrypt_aes_gcm.c index 9bc60fe..23fd4e9 100644 --- a/examples/encrypt_aes_gcm.c +++ b/examples/encrypt_aes_gcm.c @@ -52,7 +52,7 @@ void encrypt_decrypt_aes_gcm(void) size_t aad_len; size_t tag_len; - printf("Plain data (16 of %zu bytes): %.16s\n", (size_t)4096, lorem4096); + printf("Plain data (16 of %zu bytes): %.16s\n", LOREM4096_SIZE, lorem4096); /// Key generation @@ -77,6 +77,8 @@ void encrypt_decrypt_aes_gcm(void) /// Encryption { + size_t len; + ret = yaca_encrypt_init(&ctx, YACA_ENC_AES, YACA_BCM_GCM, key, iv); if (ret < 0) goto clean; @@ -85,21 +87,20 @@ void encrypt_decrypt_aes_gcm(void) if (ret < 0) goto clean; - ret = yaca_encrypt_update(ctx, lorem4096, 4096, NULL, &ciphertext_len); - if (ret != 42) - goto clean;// TODO: what error code? + ret = yaca_get_output_length(ctx, LOREM4096_SIZE, &ciphertext_len); + if (ret != 0) + goto clean; - ret = yaca_get_block_length(ctx); - if (ret < 0) + ret = yaca_get_block_length(ctx, &len); + if (ret != 0) goto clean; - ciphertext_len += ret ; // Add block size for finalize + ciphertext_len += len ; // Add block size for finalize ciphertext = yaca_malloc(ciphertext_len); if (ciphertext == NULL) goto clean; - size_t len; - ret = yaca_encrypt_update(ctx, lorem4096, 4096, ciphertext, &len); + ret = yaca_encrypt_update(ctx, lorem4096, LOREM4096_SIZE, ciphertext, &len); if (ret < 0) goto clean; @@ -132,15 +133,15 @@ void encrypt_decrypt_aes_gcm(void) if (ret < 0) goto clean; - ret = yaca_decrypt_update(ctx, ciphertext, ciphertext_len, NULL, &plaintext_len); - if (ret != 42) - goto clean; // TODO: what error code? + ret = yaca_get_output_length(ctx, ciphertext_len, &plaintext_len); + if (ret != 0) + goto clean; - ret = yaca_get_block_length(ctx); - if (ret < 0) + ret = yaca_get_block_length(ctx, &len); + if (ret != 0) goto clean; - plaintext_len += ret; // Add block size for finalize + plaintext_len += len; // Add block size for finalize plaintext = yaca_malloc(plaintext_len); if (plaintext == NULL) goto clean; diff --git a/examples/seal.c b/examples/seal.c index c75b721..4da8228 100644 --- a/examples/seal.c +++ b/examples/seal.c @@ -65,10 +65,10 @@ void encrypt_seal(void) if (yaca_seal_init(&ctx, key_pub, algo, bcm, key_bits, &aes_key, &iv) != 0) goto ex_pubk; - if ((block_len = yaca_get_block_length(ctx)) <= 0) + if (yaca_get_block_length(ctx, &block_len) != 0) goto ex_ak; - if ((output_len = yaca_get_output_length(ctx, LOREM4096_SIZE)) <= 0) + if (yaca_get_output_length(ctx, LOREM4096_SIZE, &output_len) != 0) goto ex_ak; /* Calculate max output: size of update + final chunks */ @@ -98,10 +98,10 @@ void encrypt_seal(void) if (yaca_open_init(&ctx, key_priv, algo, bcm, key_bits, aes_key, iv) != 0) goto ex_of; - if ((block_len = yaca_get_block_length(ctx)) <= 0) + if (yaca_get_block_length(ctx, &block_len) != 0) goto ex_of; - if ((output_len = yaca_get_output_length(ctx, LOREM4096_SIZE)) <= 0) + if (yaca_get_output_length(ctx, LOREM4096_SIZE, &output_len) != 0) goto ex_of; /* Calculate max output: size of update + final chunks */ diff --git a/examples/sign.c b/examples/sign.c index c5c9a5e..dab16bd 100644 --- a/examples/sign.c +++ b/examples/sign.c @@ -65,7 +65,7 @@ void sign_verify_asym(yaca_key_type_e type, const char *algo) if (yaca_sign_update(ctx, lorem4096, LOREM4096_SIZE) != 0) goto finish; - if ((signature_len = yaca_get_sign_length(ctx)) <= 0) + if (yaca_get_sign_length(ctx, &signature_len) != 0) goto finish; if ((signature = yaca_malloc(signature_len)) == NULL) @@ -123,7 +123,7 @@ void sign_verify_hmac(void) if (yaca_sign_update(ctx, lorem4096, LOREM4096_SIZE) != 0) goto finish; - if ((signature_len = yaca_get_sign_length(ctx)) <= 0) + if (yaca_get_sign_length(ctx, &signature_len) != 0) goto finish; if ((signature = yaca_malloc(signature_len)) == NULL) @@ -176,7 +176,7 @@ void sign_verify_cmac(void) if (yaca_sign_update(ctx, lorem4096, LOREM4096_SIZE)) goto finish; - if ((signature_len = yaca_get_sign_length(ctx)) <= 0) + if (yaca_get_sign_length(ctx, &signature_len) != 0) goto finish; if ((signature = yaca_malloc(signature_len)) == NULL) diff --git a/src/crypto.c b/src/crypto.c index 650bdcf..df5ba7d 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -120,10 +120,10 @@ API void yaca_ctx_free(yaca_ctx_h ctx) } } -API int yaca_get_output_length(const yaca_ctx_h ctx, size_t input_len) +API int yaca_get_output_length(const yaca_ctx_h ctx, size_t input_len, size_t *output_len) { if (ctx == YACA_CTX_NULL) return YACA_ERROR_INVALID_ARGUMENT; - return ctx->get_output_length(ctx, input_len); + return ctx->get_output_length(ctx, input_len, output_len); } diff --git a/src/digest.c b/src/digest.c index b9f4ce4..10d4dbf 100644 --- a/src/digest.c +++ b/src/digest.c @@ -49,14 +49,15 @@ static struct yaca_digest_ctx_s *get_digest_ctx(const yaca_ctx_h ctx) } } -static int get_digest_output_length(const yaca_ctx_h ctx, size_t input_len) +static int get_digest_output_length(const yaca_ctx_h ctx, size_t input_len, size_t *output_len) { struct yaca_digest_ctx_s *c = get_digest_ctx(ctx); if (c == NULL) return YACA_ERROR_INVALID_ARGUMENT; - return EVP_MD_CTX_size(c->mdctx); + *output_len = EVP_MD_CTX_size(c->mdctx); + return 0; } static void destroy_digest_context(yaca_ctx_h ctx) diff --git a/src/encrypt.c b/src/encrypt.c index ec2176f..758fd2b 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -68,7 +68,7 @@ static void destroy_encrypt_ctx(const yaca_ctx_h ctx) nc->cipher_ctx = NULL; } -static int get_encrypt_output_length(const yaca_ctx_h ctx, size_t input_len) +static int get_encrypt_output_length(const yaca_ctx_h ctx, size_t input_len, size_t *output_len) { struct yaca_encrypt_ctx_s *nc = get_encrypt_ctx(ctx); int block_size; @@ -77,14 +77,21 @@ static int get_encrypt_output_length(const yaca_ctx_h ctx, size_t input_len) return YACA_ERROR_INVALID_ARGUMENT; block_size = EVP_CIPHER_CTX_block_size(nc->cipher_ctx); - if (block_size == 0) { + if (block_size <= 0) { ERROR_DUMP(YACA_ERROR_INTERNAL); return YACA_ERROR_INTERNAL; } - if (input_len > 0) - return block_size + input_len - 1; - return block_size; + if (input_len > 0) { + if ((size_t)block_size > SIZE_MAX - input_len + 1) + return YACA_ERROR_TOO_BIG_ARGUMENT; + + *output_len = block_size + input_len - 1; + } else { + *output_len = block_size; + } + + return 0; } static const char *encrypt_algo_to_str(yaca_enc_algo_e algo) diff --git a/src/internal.h b/src/internal.h index 5d1f49a..0aa764a 100644 --- a/src/internal.h +++ b/src/internal.h @@ -46,7 +46,7 @@ struct yaca_ctx_s enum yaca_ctx_type_e type; void (*ctx_destroy)(const yaca_ctx_h ctx); - int (*get_output_length)(const yaca_ctx_h ctx, size_t input_len); + int (*get_output_length)(const yaca_ctx_h ctx, size_t input_len, size_t *output_len); int (*set_param)(yaca_ctx_h ctx, yaca_ex_param_e param, const void *value, size_t value_len); int (*get_param)(const yaca_ctx_h ctx, yaca_ex_param_e param, diff --git a/src/seal.c b/src/seal.c index a5fb2ae..586aac1 100644 --- a/src/seal.c +++ b/src/seal.c @@ -68,7 +68,7 @@ static void destroy_seal_ctx(const yaca_ctx_h ctx) nc->cipher_ctx = NULL; } -static int get_seal_output_length(const yaca_ctx_h ctx, size_t input_len) +static int get_seal_output_length(const yaca_ctx_h ctx, size_t input_len, size_t *output_len) { struct yaca_seal_ctx_s *nc = get_seal_ctx(ctx); int block_size; @@ -83,9 +83,16 @@ static int get_seal_output_length(const yaca_ctx_h ctx, size_t input_len) return YACA_ERROR_INTERNAL; } - if (input_len > 0) - return block_size + input_len - 1; - return block_size; + if (input_len > 0) { + if ((size_t)block_size > SIZE_MAX - input_len + 1) + return YACA_ERROR_TOO_BIG_ARGUMENT; + + *output_len = block_size + input_len - 1; + } else { + *output_len = block_size; + } + + return 0; } static int seal_init(yaca_ctx_h *ctx, diff --git a/src/sign.c b/src/sign.c index b885cc6..e629210 100644 --- a/src/sign.c +++ b/src/sign.c @@ -56,7 +56,7 @@ 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) +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); @@ -75,7 +75,8 @@ static int get_sign_output_length(const yaca_ctx_h ctx, size_t input_len) return YACA_ERROR_INVALID_ARGUMENT; } - return len; + *output_len = len; + return 0; } static void destroy_sign_context(yaca_ctx_h ctx) diff --git a/src/simple.c b/src/simple.c index bb8eeec..d82d4f2 100644 --- a/src/simple.c +++ b/src/simple.c @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -52,11 +53,10 @@ API int yaca_digest_calc(yaca_digest_algo_e algo, if (ret < 0) goto err; - ret = yaca_get_digest_length(ctx); - if (ret < 0) + ret = yaca_get_digest_length(ctx, &ldigest_len); + if (ret != 0) goto err; - ldigest_len = ret; ldigest = yaca_malloc(ldigest_len); if (!ldigest) goto err; @@ -97,24 +97,24 @@ API int yaca_encrypt(yaca_enc_algo_e algo, sym_key == YACA_KEY_NULL) return YACA_ERROR_INVALID_ARGUMENT; - if (plain_len > INT_MAX) /* TODO: this is because get_output_length returns signed int - perhaps we should change that */ - return YACA_ERROR_TOO_BIG_ARGUMENT; - ret = yaca_encrypt_init(&ctx, algo, bcm, sym_key, iv); if (ret != 0) return ret; - ret = yaca_get_block_length(ctx); - if (ret <= 0) + ret = yaca_get_block_length(ctx, &lcipher_len); + if (ret != 0) goto err; - lcipher_len = ret; + ret = yaca_get_output_length(ctx, plain_len, &out_len); + if (ret != 0) + goto err; - ret = yaca_get_output_length(ctx, plain_len); - if (ret <= 0) + if (out_len > SIZE_MAX - lcipher_len) { + ret = YACA_ERROR_TOO_BIG_ARGUMENT; goto err; + } - lcipher_len += ret; + lcipher_len += out_len; lcipher = yaca_malloc(lcipher_len); if (lcipher == NULL) @@ -174,24 +174,24 @@ API int yaca_decrypt(yaca_enc_algo_e algo, sym_key == YACA_KEY_NULL) return YACA_ERROR_INVALID_ARGUMENT; - if (cipher_len > INT_MAX) /* TODO: this is because get_output_length returns signed int - perhaps we should change that */ - return YACA_ERROR_TOO_BIG_ARGUMENT; - ret = yaca_decrypt_init(&ctx, algo, bcm, sym_key, iv); if (ret != 0) return ret; - ret = yaca_get_block_length(ctx); - if (ret <= 0) + ret = yaca_get_block_length(ctx, &lplain_len); + if (ret != 0) goto err; - lplain_len = ret; + ret = yaca_get_output_length(ctx, cipher_len, &out_len); + if (ret != 0) + goto err; - ret = yaca_get_output_length(ctx, cipher_len); - if (ret <= 0) + if (out_len > SIZE_MAX - lplain_len) { + ret = YACA_ERROR_TOO_BIG_ARGUMENT; goto err; + } - lplain_len += ret; + lplain_len += out_len; lplain = yaca_malloc(lplain_len); if (!lplain) -- 2.7.4