Replace spaces with tabs
[platform/core/security/yaca.git] / src / simple.c
index 3db1098..e4c7a38 100644 (file)
  */
 
 #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;
        }
@@ -267,91 +298,109 @@ static int sign(const yaca_ctx_h ctx, const char *data, size_t data_len,
        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;
 }