New flags EVP_CIPH_FLAG_CUSTOM_CIPHER in cipher structures if an underlying
[openssl.git] / crypto / evp / evp_enc.c
index a35621a2ec9d27fc3db44baf9bb499b8711b0e5e..3f8473b348a653cb7a59e7921ca6893eb5b7dd13 100644 (file)
@@ -204,16 +204,20 @@ skip_to_init:
                        case EVP_CIPH_OFB_MODE:
 
                        ctx->num = 0;
+                       /* fall-through */
 
                        case EVP_CIPH_CBC_MODE:
-                       case EVP_CIPH_CTR_MODE:
 
                        OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) <=
                                        (int)sizeof(ctx->iv));
                        if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
+                       memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
+                       break;
+
+                       case EVP_CIPH_CTR_MODE:
                        /* Don't reuse IV for CTR mode */
-                       if (EVP_CIPHER_CTX_mode(ctx) != EVP_CIPH_CTR_MODE)
-                               memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
+                       if(iv)
+                               memcpy(ctx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx));
                        break;
 
                        default:
@@ -282,6 +286,16 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
        {
        int i,j,bl;
 
+       if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER)
+               {
+               i = ctx->cipher->do_cipher(ctx, out, in, inl);
+               if (i < 0)
+                       return 0;
+               else
+                       *outl = i;
+               return 1;
+               }
+
        if (inl <= 0)
                {
                *outl = 0;
@@ -352,6 +366,16 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
        int n,ret;
        unsigned int i, b, bl;
 
+       if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER)
+               {
+               i = ctx->cipher->do_cipher(ctx, out, NULL, -1);
+               if (i < 0)
+                       return 0;
+               else
+                       *outl = i;
+               return 1;
+               }
+
        b=ctx->cipher->block_size;
        OPENSSL_assert(b <= sizeof ctx->buf);
        if (b == 1)
@@ -389,6 +413,19 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
        int fix_len;
        unsigned int b;
 
+       if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER)
+               {
+               fix_len = ctx->cipher->do_cipher(ctx, out, in, inl);
+               if (fix_len < 0)
+                       {
+                       *outl = 0;
+                       return 0;
+                       }
+               else
+                       *outl = fix_len;
+               return 1;
+               }
+
        if (inl <= 0)
                {
                *outl = 0;
@@ -442,8 +479,18 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
        {
        int i,n;
        unsigned int b;
-
        *outl=0;
+
+       if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER)
+               {
+               i = ctx->cipher->do_cipher(ctx, out, NULL, -1);
+               if (i < 0)
+                       return 0;
+               else
+                       *outl = i;
+               return 1;
+               }
+
        b=ctx->cipher->block_size;
        if (ctx->flags & EVP_CIPH_NO_PADDING)
                {