Add support to CAST5 encrypt/decrypt. Update documentation. 57/68957/7
authorDariusz Michaluk <d.michaluk@samsung.com>
Tue, 10 May 2016 12:57:30 +0000 (14:57 +0200)
committerDariusz Michaluk <d.michaluk@samsung.com>
Mon, 16 May 2016 08:32:32 +0000 (10:32 +0200)
Change-Id: I645018182fc723190223eac627c665d84da41340

api/yaca/types.h
src/encrypt.c

index 4363932..3397e86 100644 (file)
@@ -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,
 
index ad2334b..d185c16 100644 (file)
@@ -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;