*/
#include <assert.h>
-#include <limits.h>
#include <stdint.h>
-#include <openssl/crypto.h>
-#include <openssl/rand.h>
-
-#include <yaca/crypto.h>
-#include <yaca/error.h>
-#include <yaca/encrypt.h>
-#include <yaca/digest.h>
-#include <yaca/key.h>
-#include <yaca/sign.h>
+#include <yaca_crypto.h>
+#include <yaca_error.h>
+#include <yaca_encrypt.h>
+#include <yaca_digest.h>
+#include <yaca_key.h>
+#include <yaca_sign.h>
#include "internal.h"
-API int yaca_digest_calc(yaca_digest_algo_e algo,
- const char *data,
- size_t data_len,
- char **digest,
- size_t *digest_len)
+API int yaca_simple_calculate_digest(yaca_digest_algorithm_e algo,
+ const char *data,
+ size_t data_len,
+ char **digest,
+ size_t *digest_len)
{
- yaca_ctx_h ctx;
+ yaca_context_h ctx;
int ret;
- char *ldigest;
+ char *ldigest = NULL;
size_t ldigest_len;
- if (data == NULL || data_len == 0 || digest == NULL || digest_len == NULL)
- return YACA_ERROR_INVALID_ARGUMENT;
+ if ((data == NULL && data_len > 0) || (data != NULL && data_len == 0) ||
+ digest == NULL || digest_len == NULL)
+ return YACA_ERROR_INVALID_PARAMETER;
- ret = yaca_digest_init(&ctx, algo);
- if (ret != 0)
+ ret = yaca_digest_initialize(&ctx, algo);
+ if (ret != YACA_ERROR_NONE)
return ret;
- ret = yaca_digest_update(ctx, data, data_len);
- if (ret != 0)
- goto err;
+ if (data_len > 0) {
+ ret = yaca_digest_update(ctx, data, data_len);
+ if (ret != YACA_ERROR_NONE)
+ goto exit;
+ }
- ret = yaca_get_digest_length(ctx, &ldigest_len);
- if (ret != 0)
- goto err;
+ ret = yaca_context_get_output_length(ctx, 0, &ldigest_len);
+ if (ret != YACA_ERROR_NONE)
+ goto exit;
- ldigest = yaca_malloc(ldigest_len);
- if (!ldigest)
- goto err;
+ assert(ldigest_len > 0);
- ret = yaca_digest_final(ctx, ldigest, &ldigest_len);
- if (ret != 0)
- goto err_free;
+ ret = yaca_malloc(ldigest_len, (void**)&ldigest);
+ if (ret != YACA_ERROR_NONE)
+ goto exit;
- yaca_ctx_free(ctx);
+ ret = yaca_digest_finalize(ctx, ldigest, &ldigest_len);
+ if (ret != YACA_ERROR_NONE)
+ goto exit;
*digest_len = ldigest_len;
*digest = ldigest;
- return 0;
+ ldigest = NULL;
-err_free:
+exit:
yaca_free(ldigest);
-err:
- yaca_ctx_free(ctx);
+ yaca_context_destroy(ctx);
+
return ret;
}
-API int yaca_encrypt(yaca_enc_algo_e algo,
- yaca_block_cipher_mode_e bcm,
- const yaca_key_h sym_key,
- const yaca_key_h iv,
- const char *plain,
- size_t plain_len,
- char **cipher,
- size_t *cipher_len)
+API int yaca_simple_encrypt(yaca_encrypt_algorithm_e algo,
+ yaca_block_cipher_mode_e bcm,
+ const yaca_key_h sym_key,
+ const yaca_key_h iv,
+ const char *plaintext,
+ size_t plaintext_len,
+ char **ciphertext,
+ size_t *ciphertext_len)
{
- yaca_ctx_h ctx;
+ yaca_context_h ctx;
int ret;
- char *lcipher;
- char *rcipher;
- size_t out_len, lcipher_len, written;
-
- if (plain == NULL || plain_len == 0 || cipher == NULL || cipher_len == NULL ||
- sym_key == YACA_KEY_NULL)
- return YACA_ERROR_INVALID_ARGUMENT;
-
- ret = yaca_encrypt_init(&ctx, algo, bcm, sym_key, iv);
- if (ret != 0)
+ char *lciphertext = NULL;
+ size_t out_len = 0;
+ size_t lciphertext_len = 0;
+ size_t written = 0;
+
+ if ((plaintext == NULL && plaintext_len > 0) || (plaintext != NULL && plaintext_len == 0) ||
+ ciphertext == NULL || ciphertext_len == NULL ||
+ sym_key == YACA_KEY_NULL ||
+ bcm == YACA_BCM_CCM || bcm == YACA_BCM_GCM)
+ return YACA_ERROR_INVALID_PARAMETER;
+
+ ret = yaca_encrypt_initialize(&ctx, algo, bcm, sym_key, iv);
+ if (ret != YACA_ERROR_NONE)
return ret;
- ret = yaca_get_block_length(ctx, &lcipher_len);
- if (ret != 0)
- goto err;
+ if (plaintext_len > 0) {
+ ret = yaca_context_get_output_length(ctx, plaintext_len, &out_len);
+ if (ret != YACA_ERROR_NONE)
+ goto exit;
+ }
- ret = yaca_get_output_length(ctx, plain_len, &out_len);
- if (ret != 0)
- goto err;
+ ret = yaca_context_get_output_length(ctx, 0, &lciphertext_len);
+ if (ret != YACA_ERROR_NONE)
+ goto exit;
- if (out_len > SIZE_MAX - lcipher_len) {
- ret = YACA_ERROR_TOO_BIG_ARGUMENT;
- goto err;
+ if (out_len > SIZE_MAX - lciphertext_len) {
+ ret = YACA_ERROR_INVALID_PARAMETER;
+ goto exit;
}
- lcipher_len += out_len;
-
- lcipher = yaca_malloc(lcipher_len);
- if (lcipher == NULL)
- goto err;
+ lciphertext_len += out_len;
+ assert(lciphertext_len > 0);
- out_len = lcipher_len;
- ret = yaca_encrypt_update(ctx, plain, plain_len, lcipher, &out_len);
- if (ret != 0)
- goto err_free;
+ ret = yaca_malloc(lciphertext_len, (void**)&lciphertext);
+ if (ret != YACA_ERROR_NONE)
+ goto exit;
- assert (out_len <= lcipher_len);
+ if (plaintext_len > 0) {
+ ret = yaca_encrypt_update(ctx, plaintext, plaintext_len, lciphertext, &out_len);
+ if (ret != YACA_ERROR_NONE)
+ goto exit;
+ }
+ assert(out_len <= lciphertext_len);
written = out_len;
- out_len = lcipher_len - written;
- ret = yaca_encrypt_final(ctx, lcipher + written, &out_len);
- if (ret != 0)
- goto err_free;
+
+ ret = yaca_encrypt_finalize(ctx, lciphertext + written, &out_len);
+ if (ret != YACA_ERROR_NONE)
+ goto exit;
written += out_len;
- assert (written <= lcipher_len);
+ assert(written <= lciphertext_len);
+
+ if (((bcm == YACA_BCM_CBC || bcm == YACA_BCM_ECB) && written == 0) ||
+ (bcm != YACA_BCM_CBC && bcm != YACA_BCM_ECB && plaintext_len == 0 && written > 0)) {
+ ret = YACA_ERROR_INTERNAL;
+ goto exit;
+ }
- rcipher = yaca_realloc(lcipher, written);
- if (rcipher == NULL) {
- ret = YACA_ERROR_OUT_OF_MEMORY;
- goto err_free;
+ if (written > 0) {
+ ret = yaca_realloc(written, (void**)&lciphertext);
+ if (ret != YACA_ERROR_NONE)
+ goto exit;
+ } else {
+ yaca_free(lciphertext);
+ lciphertext = NULL;
}
- yaca_ctx_free(ctx);
+ *ciphertext = lciphertext;
+ *ciphertext_len = written;
+ lciphertext = NULL;
+ ret = YACA_ERROR_NONE;
- *cipher = rcipher;
- *cipher_len = written;
- return 0;
+exit:
+ yaca_free(lciphertext);
+ yaca_context_destroy(ctx);
-err_free:
- yaca_free(lcipher);
-err:
- yaca_ctx_free(ctx);
return ret;
}
-API int yaca_decrypt(yaca_enc_algo_e algo,
- yaca_block_cipher_mode_e bcm,
- const yaca_key_h sym_key,
- const yaca_key_h iv,
- const char *cipher,
- size_t cipher_len,
- char **plain,
- size_t *plain_len)
+API int yaca_simple_decrypt(yaca_encrypt_algorithm_e algo,
+ yaca_block_cipher_mode_e bcm,
+ const yaca_key_h sym_key,
+ const yaca_key_h iv,
+ const char *ciphertext,
+ size_t ciphertext_len,
+ char **plaintext,
+ size_t *plaintext_len)
{
- yaca_ctx_h ctx;
+ yaca_context_h ctx;
int ret;
- char *lplain;
- char *rplain;
- size_t out_len, lplain_len, written;
-
- if (cipher == NULL || cipher_len == 0 || plain == NULL || plain_len == NULL ||
- sym_key == YACA_KEY_NULL)
- return YACA_ERROR_INVALID_ARGUMENT;
-
- ret = yaca_decrypt_init(&ctx, algo, bcm, sym_key, iv);
- if (ret != 0)
+ char *lplaintext = NULL;
+ size_t out_len = 0;
+ size_t lplaintext_len = 0;
+ size_t written = 0;
+
+ if ((ciphertext == NULL && ciphertext_len > 0) || (ciphertext != NULL && ciphertext_len == 0) ||
+ ((bcm == YACA_BCM_ECB || bcm == YACA_BCM_CBC) && ciphertext == NULL && ciphertext_len == 0) ||
+ plaintext == NULL || plaintext_len == NULL ||
+ sym_key == YACA_KEY_NULL ||
+ bcm == YACA_BCM_CCM || bcm == YACA_BCM_GCM)
+ return YACA_ERROR_INVALID_PARAMETER;
+
+ ret = yaca_decrypt_initialize(&ctx, algo, bcm, sym_key, iv);
+ if (ret != YACA_ERROR_NONE)
return ret;
- ret = yaca_get_block_length(ctx, &lplain_len);
- if (ret != 0)
- goto err;
+ if (ciphertext_len > 0) {
+ ret = yaca_context_get_output_length(ctx, ciphertext_len, &out_len);
+ if (ret != YACA_ERROR_NONE)
+ goto exit;
+ }
- ret = yaca_get_output_length(ctx, cipher_len, &out_len);
- if (ret != 0)
- goto err;
+ ret = yaca_context_get_output_length(ctx, 0, &lplaintext_len);
+ if (ret != YACA_ERROR_NONE)
+ goto exit;
- if (out_len > SIZE_MAX - lplain_len) {
- ret = YACA_ERROR_TOO_BIG_ARGUMENT;
- goto err;
+ if (out_len > SIZE_MAX - lplaintext_len) {
+ ret = YACA_ERROR_INVALID_PARAMETER;
+ goto exit;
}
- lplain_len += out_len;
+ lplaintext_len += out_len;
+ assert(lplaintext_len > 0);
- lplain = yaca_malloc(lplain_len);
- if (!lplain)
- goto err;
+ ret = yaca_malloc(lplaintext_len, (void**)&lplaintext);
+ if (ret != YACA_ERROR_NONE)
+ goto exit;
- out_len = lplain_len;
- ret = yaca_decrypt_update(ctx, cipher, cipher_len, lplain, &out_len);
- if (ret != 0)
- goto err_free;
-
- assert(out_len <= lplain_len);
+ if (ciphertext_len > 0) {
+ ret = yaca_decrypt_update(ctx, ciphertext, ciphertext_len, lplaintext, &out_len);
+ if (ret != YACA_ERROR_NONE)
+ goto exit;
+ }
+ assert(out_len <= lplaintext_len);
written = out_len;
- out_len = lplain_len - written;
- ret = yaca_decrypt_final(ctx, lplain + written, &out_len);
- if (ret != 0)
- goto err_free;
+
+ ret = yaca_decrypt_finalize(ctx, lplaintext + written, &out_len);
+ if (ret != YACA_ERROR_NONE)
+ goto exit;
written += out_len;
- assert(written <= lplain_len);
+ assert(written <= lplaintext_len);
- rplain = yaca_realloc(lplain, written);
- if (rplain == NULL) {
- ret = YACA_ERROR_OUT_OF_MEMORY;
- goto err_free;
+ if (bcm != YACA_BCM_CBC && bcm != YACA_BCM_ECB && ciphertext_len == 0 && written > 0) {
+ ret = YACA_ERROR_INTERNAL;
+ goto exit;
}
- yaca_ctx_free(ctx);
+ if (written > 0) {
+ ret = yaca_realloc(written, (void**)&lplaintext);
+ if (ret != YACA_ERROR_NONE)
+ goto exit;
+ } else {
+ yaca_free(lplaintext);
+ lplaintext = NULL;
+ }
- *plain = rplain;
- *plain_len = written;
- return 0;
+ *plaintext = lplaintext;
+ *plaintext_len = written;
+ lplaintext = NULL;
+ ret = YACA_ERROR_NONE;
+
+exit:
+ yaca_free(lplaintext);
+ yaca_context_destroy(ctx);
-err_free:
- yaca_free(lplain);
-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)
+static int sign(const yaca_context_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;
+ if (data_len > 0) {
+ ret = yaca_sign_update(ctx, data, data_len);
+ if (ret != YACA_ERROR_NONE)
+ return ret;
+ }
- ret = yaca_get_sign_length(ctx, signature_len);
- if (ret != 0)
+ ret = yaca_context_get_output_length(ctx, 0, signature_len);
+ if (ret != YACA_ERROR_NONE)
return ret;
- *signature = yaca_malloc(*signature_len);
- if (signature == NULL)
- return YACA_ERROR_OUT_OF_MEMORY;
+ assert(*signature_len > 0);
- ret = yaca_sign_final(ctx, *signature, signature_len);
- if (ret != 0) {
+ ret = yaca_malloc(*signature_len, (void**)signature);
+ if (ret != YACA_ERROR_NONE)
+ return ret;
+
+ ret = yaca_sign_finalize(ctx, *signature, signature_len);
+ if (ret != YACA_ERROR_NONE) {
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)
+API int yaca_simple_calculate_signature(yaca_digest_algorithm_e algo,
+ const yaca_key_h prv_key,
+ const char *data,
+ size_t data_len,
+ char **signature,
+ size_t *signature_len)
{
int ret;
- yaca_ctx_h ctx = YACA_CTX_NULL;
+ yaca_context_h ctx = YACA_CONTEXT_NULL;
- ret = yaca_sign_init(&ctx, algo, key);
- if (ret != 0)
+ if ((data == NULL && data_len > 0) || (data != NULL && data_len == 0) ||
+ signature == NULL || signature_len == NULL)
+ return YACA_ERROR_INVALID_PARAMETER;
+
+ ret = yaca_sign_initialize(&ctx, algo, prv_key);
+ if (ret != YACA_ERROR_NONE)
return ret;
ret = sign(ctx, data, data_len, signature, signature_len);
- yaca_ctx_free(ctx);
+ yaca_context_destroy(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)
+API int yaca_simple_verify_signature(yaca_digest_algorithm_e algo,
+ const yaca_key_h pub_key,
+ const char *data,
+ size_t data_len,
+ const char *signature,
+ size_t signature_len)
{
int ret;
- yaca_ctx_h ctx = YACA_CTX_NULL;
+ yaca_context_h ctx = YACA_CONTEXT_NULL;
+
+ if ((data == NULL && data_len > 0) || (data != NULL && data_len == 0) ||
+ signature == NULL || signature_len == 0)
+ return YACA_ERROR_INVALID_PARAMETER;
- ret = yaca_verify_init(&ctx, algo, key);
- if (ret != 0)
+ ret = yaca_verify_initialize(&ctx, algo, pub_key);
+ if (ret != YACA_ERROR_NONE)
return ret;
- ret = yaca_verify_update(ctx, data, data_len);
- if (ret != 0)
- goto free_ctx;
+ if (data_len > 0) {
+ ret = yaca_verify_update(ctx, data, data_len);
+ if (ret != YACA_ERROR_NONE)
+ goto exit;
+ }
- ret = yaca_verify_final(ctx, signature, signature_len);
+ ret = yaca_verify_finalize(ctx, signature, signature_len);
-free_ctx:
- yaca_ctx_free(ctx);
+exit:
+ yaca_context_destroy(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)
+API int yaca_simple_calculate_hmac(yaca_digest_algorithm_e algo,
+ const yaca_key_h sym_key,
+ const char *data,
+ size_t data_len,
+ char **mac,
+ size_t *mac_len)
{
int ret;
- yaca_ctx_h ctx = YACA_CTX_NULL;
+ yaca_context_h ctx = YACA_CONTEXT_NULL;
+
+ if ((data == NULL && data_len > 0) || (data != NULL && data_len == 0) ||
+ mac == NULL || mac_len == NULL)
+ return YACA_ERROR_INVALID_PARAMETER;
- ret = yaca_sign_hmac_init(&ctx, algo, key);
- if (ret != 0)
+ ret = yaca_sign_initialize_hmac(&ctx, algo, sym_key);
+ if (ret != YACA_ERROR_NONE)
return ret;
ret = sign(ctx, data, data_len, mac, mac_len);
- yaca_ctx_free(ctx);
+ yaca_context_destroy(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)
+API int yaca_simple_calculate_cmac(yaca_encrypt_algorithm_e algo,
+ const yaca_key_h sym_key,
+ const char *data,
+ size_t data_len,
+ char **mac,
+ size_t *mac_len)
{
int ret;
- yaca_ctx_h ctx = YACA_CTX_NULL;
+ yaca_context_h ctx = YACA_CONTEXT_NULL;
+
+ if ((data == NULL && data_len > 0) || (data != NULL && data_len == 0) ||
+ mac == NULL || mac_len == NULL)
+ return YACA_ERROR_INVALID_PARAMETER;
- ret = yaca_sign_cmac_init(&ctx, algo, key);
- if (ret != 0)
+ ret = yaca_sign_initialize_cmac(&ctx, algo, sym_key);
+ if (ret != YACA_ERROR_NONE)
return ret;
ret = sign(ctx, data, data_len, mac, mac_len);
- yaca_ctx_free(ctx);
+ yaca_context_destroy(ctx);
return ret;
}