Make sure yaca_*alloc() is not called with 0 size 06/73006/3
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Fri, 3 Jun 2016 12:45:49 +0000 (14:45 +0200)
committerLukasz Pawelczyk <l.pawelczyk@samsung.com>
Mon, 6 Jun 2016 12:45:11 +0000 (14:45 +0200)
- Add asserts
- Don't install static locks if CRYPTO_num_locks == 0
- Treat 0 output length as YACA_ERROR_INTERNAL:
  - If client provided a 0-length key we should detect it in yaca_sign_*init()
    and prevent him from using it. If it has 0 length in
    get_sign_output_length() it's an internal error.

Change-Id: I5d2d4063c568f76a25ee616b40c99abd5cc4dfa9

src/crypto.c
src/digest.c
src/encrypt.c
src/key.c
src/sign.c
src/simple.c

index 79ead7a..a907b6a 100644 (file)
@@ -94,32 +94,34 @@ API int yaca_init(void)
        OpenSSL_add_all_ciphers();
 
        /* enable threads support */
-       ret = yaca_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t), (void**)&mutexes);
-       if (ret != YACA_ERROR_NONE)
-               return ret;
+       if (CRYPTO_num_locks() > 0) {
+               ret = yaca_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t), (void**)&mutexes);
+               if (ret != YACA_ERROR_NONE)
+                       return ret;
 
-       for (int i = 0; i < CRYPTO_num_locks(); i++) {
-               if (pthread_mutex_init(&mutexes[i], NULL) != 0) {
-                       int ret = YACA_ERROR_NONE;
-                       switch (errno) {
-                       case ENOMEM:
-                               ret = YACA_ERROR_OUT_OF_MEMORY;
-                               break;
-                       case EAGAIN:
-                       case EPERM:
-                       case EBUSY:
-                       case EINVAL:
-                       default:
-                               ret = YACA_ERROR_INTERNAL;
+               for (int i = 0; i < CRYPTO_num_locks(); i++) {
+                       if (pthread_mutex_init(&mutexes[i], NULL) != 0) {
+                               int ret = YACA_ERROR_NONE;
+                               switch (errno) {
+                               case ENOMEM:
+                                       ret = YACA_ERROR_OUT_OF_MEMORY;
+                                       break;
+                               case EAGAIN:
+                               case EPERM:
+                               case EBUSY:
+                               case EINVAL:
+                               default:
+                                       ret = YACA_ERROR_INTERNAL;
+                               }
+                               destroy_mutexes(i);
+
+                               return ret;
                        }
-                       destroy_mutexes(i);
-
-                       return ret;
                }
-       }
 
-       CRYPTO_set_id_callback(thread_id_callback);
-       CRYPTO_set_locking_callback(locking_callback);
+               CRYPTO_set_id_callback(thread_id_callback);
+               CRYPTO_set_locking_callback(locking_callback);
+       }
 
        /*
          TODO:
index d36ce67..7b20409 100644 (file)
@@ -57,7 +57,12 @@ static int get_digest_output_length(const yaca_ctx_h ctx, size_t input_len, size
        if (c == NULL)
                return YACA_ERROR_INVALID_ARGUMENT;
 
-       *output_len = EVP_MD_CTX_size(c->mdctx);
+       int md_size = EVP_MD_CTX_size(c->mdctx);
+       if (md_size <= 0)
+               return YACA_ERROR_INTERNAL;
+
+       *output_len = md_size;
+
        return YACA_ERROR_NONE;
 }
 
index ab623f9..6d7b34e 100644 (file)
@@ -93,6 +93,8 @@ static int get_encrypt_output_length(const yaca_ctx_h ctx, size_t input_len, siz
        } else {
                *output_len = block_size;
        }
+       if (*output_len == 0)
+               return YACA_ERROR_INTERNAL;
 
        return YACA_ERROR_NONE;
 }
index 7f7a605..0642409 100644 (file)
--- a/src/key.c
+++ b/src/key.c
@@ -407,6 +407,8 @@ int export_simple_raw(struct yaca_key_simple_s *simple_key,
 
        size_t key_len = simple_key->bits / 8;
 
+       assert(key_len > 0);
+
        ret = yaca_malloc(key_len, (void**)data);
        if (ret != YACA_ERROR_NONE)
                return ret;
index 2d8046d..47f65a8 100644 (file)
@@ -79,14 +79,14 @@ static int get_sign_output_length(const yaca_ctx_h ctx,
 
        EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(c->mdctx->pctx);
        if (pkey == NULL) {
-               ERROR_DUMP(YACA_ERROR_INVALID_ARGUMENT);
-               return YACA_ERROR_INVALID_ARGUMENT;
+               ERROR_DUMP(YACA_ERROR_INTERNAL);
+               return YACA_ERROR_INTERNAL;
        }
 
-       size_t len = EVP_PKEY_size(pkey);
+       int len = EVP_PKEY_size(pkey);
        if (len <= 0) {
-               ERROR_DUMP(YACA_ERROR_INVALID_ARGUMENT);
-               return YACA_ERROR_INVALID_ARGUMENT;
+               ERROR_DUMP(YACA_ERROR_INTERNAL);
+               return YACA_ERROR_INTERNAL;
        }
 
        *output_len = len;
index 889e858..53a34fd 100644 (file)
@@ -59,6 +59,8 @@ API int yaca_digest_calc(yaca_digest_algo_e algo,
        if (ret != YACA_ERROR_NONE)
                goto exit;
 
+       assert(ldigest_len > 0);
+
        ret = yaca_malloc(ldigest_len, (void**)&ldigest);
        if (ret != YACA_ERROR_NONE)
                goto exit;
@@ -115,6 +117,8 @@ API int yaca_encrypt(yaca_enc_algo_e algo,
 
        lcipher_len += out_len;
 
+       assert(lcipher_len > 0);
+
        ret = yaca_malloc(lcipher_len, (void**)&lcipher);
        if (ret != YACA_ERROR_NONE)
                goto exit;
@@ -133,7 +137,7 @@ API int yaca_encrypt(yaca_enc_algo_e algo,
                goto exit;
 
        written += out_len;
-       assert(written <= lcipher_len);
+       assert(written <= lcipher_len && written > 0);
 
        ret = yaca_realloc(written, (void**)&lcipher);
        if (ret != YACA_ERROR_NONE)
@@ -187,6 +191,7 @@ API int yaca_decrypt(yaca_enc_algo_e algo,
        }
 
        lplain_len += out_len;
+       assert(lplain_len > 0);
 
        ret = yaca_malloc(lplain_len, (void**)&lplain);
        if (ret != YACA_ERROR_NONE)
@@ -206,7 +211,7 @@ API int yaca_decrypt(yaca_enc_algo_e algo,
                goto exit;
 
        written += out_len;
-       assert(written <= lplain_len);
+       assert(written <= lplain_len && written > 0);
 
        ret = yaca_realloc(written, (void**)&lplain);
        if (ret != YACA_ERROR_NONE)
@@ -240,6 +245,8 @@ static int sign(const yaca_ctx_h ctx, const char *data, size_t data_len,
        if (ret != YACA_ERROR_NONE)
                return ret;
 
+       assert(*signature_len > 0);
+
        ret = yaca_malloc(*signature_len, (void**)signature);
        if (ret != YACA_ERROR_NONE)
                return ret;