New flags EVP_CIPH_FLAG_CUSTOM_CIPHER in cipher structures if an underlying
authorDr. Stephen Henson <steve@openssl.org>
Mon, 7 Feb 2011 14:36:08 +0000 (14:36 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Mon, 7 Feb 2011 14:36:08 +0000 (14:36 +0000)
cipher handles all cipher symantics itself.

CHANGES
crypto/evp/evp.h
crypto/evp/evp_enc.c

diff --git a/CHANGES b/CHANGES
index c76090d41ce2ed48f52d231e2dc6a8ded7faff00..2b052dd850cd016e0f7015629e04d804d4c2c46b 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,16 @@
 
  Changes between 1.0.1 and 1.1.0  [xx XXX xxxx]
 
+  *) New flag in ciphers: EVP_CIPH_FLAG_CUSTOM_CIPHER. This means the
+     underlying do_cipher function handles all cipher semantics itself
+     including padding and finalisation. This is useful if (for example)
+     an ENGINE cipher handles block padding itself. The behaviour of
+     do_cipher is subtly changed if this flag is set: the return value
+     is the number of characters written to the output buffer (zero is
+     no longer an error code) or a negative error code. Also if the
+     input buffer is NULL and length -1 finalisation should be performed.
+     [Steve Henson]
+
   *) If a candidate issuer certificate is already part of the constructed
      path ignore it: new debug notification X509_V_ERR_PATH_LOOP for this case.
      [Steve Henson]
index 2fa0aa916e842b756bc6f97820faa6fedfe197e8..6604f3484b363db8dbf76b917f37dcacfcf69cbc 100644 (file)
@@ -354,6 +354,10 @@ struct evp_cipher_st
 #define                EVP_CIPH_FLAG_FIPS              0x4000
 /* Allow non FIPS cipher in FIPS mode */
 #define                EVP_CIPH_FLAG_NON_FIPS_ALLOW    0x8000
+/* Cipher handles any and all padding logic as well
+ * as finalisation.
+ */
+#define        EVP_CIPH_FLAG_CUSTOM_CIPHER     0x10000
 
 /* ctrl() values */
 
index a0bdf9856c1d07edf2a77012ee33399ef4197d4f..3f8473b348a653cb7a59e7921ca6893eb5b7dd13 100644 (file)
@@ -286,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;
@@ -356,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)
@@ -393,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;
@@ -446,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)
                {