size_t-fy EVP_CIPHER. Note that being size_t-fied it doesn't require
authorAndy Polyakov <appro@openssl.org>
Fri, 31 Oct 2008 19:48:25 +0000 (19:48 +0000)
committerAndy Polyakov <appro@openssl.org>
Fri, 31 Oct 2008 19:48:25 +0000 (19:48 +0000)
underlying cipher to be size_t-fied, it allows for size_t, signed and
unsigned long. It maintains source and even binary compatibility.

crypto/evp/e_des.c
crypto/evp/e_des3.c
crypto/evp/e_idea.c
crypto/evp/e_null.c
crypto/evp/e_rc4.c
crypto/evp/e_xcbc_d.c
crypto/evp/evp.h
crypto/evp/evp_locl.h

index 4136af4..1e42304 100644 (file)
@@ -72,7 +72,7 @@ static int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
 /* Because of various casts and different names can't use IMPLEMENT_BLOCK_CIPHER */
 
 static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-                         const unsigned char *in, unsigned int inl)
+                         const unsigned char *in, size_t inl)
 {
        BLOCK_CIPHER_ecb_loop()
                DES_ecb_encrypt((DES_cblock *)(in + i), (DES_cblock *)(out + i), ctx->cipher_data, ctx->encrypt);
@@ -80,24 +80,52 @@ static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
 }
 
 static int des_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-                         const unsigned char *in, unsigned int inl)
+                         const unsigned char *in, size_t inl)
 {
-       DES_ofb64_encrypt(in, out, (long)inl, ctx->cipher_data, (DES_cblock *)ctx->iv, &ctx->num);
+       while(inl>=EVP_MAXCHUNK)
+               {
+               DES_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data,
+                               (DES_cblock *)ctx->iv, &ctx->num);
+               inl-=EVP_MAXCHUNK;
+               in +=EVP_MAXCHUNK;
+               out+=EVP_MAXCHUNK;
+               }
+       if (inl)
+               DES_ofb64_encrypt(in, out, (long)inl, ctx->cipher_data,
+                               (DES_cblock *)ctx->iv, &ctx->num);
        return 1;
 }
 
 static int des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-                         const unsigned char *in, unsigned int inl)
+                         const unsigned char *in, size_t inl)
 {
-       DES_ncbc_encrypt(in, out, (long)inl, ctx->cipher_data,
-                        (DES_cblock *)ctx->iv, ctx->encrypt);
+       while(inl>=EVP_MAXCHUNK)
+               {
+               DES_ncbc_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data,
+                               (DES_cblock *)ctx->iv, ctx->encrypt);
+               inl-=EVP_MAXCHUNK;
+               in +=EVP_MAXCHUNK;
+               out+=EVP_MAXCHUNK;
+               }
+       if (inl)
+               DES_ncbc_encrypt(in, out, (long)inl, ctx->cipher_data,
+                               (DES_cblock *)ctx->iv, ctx->encrypt);
        return 1;
 }
 
 static int des_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-                           const unsigned char *in, unsigned int inl)
+                           const unsigned char *in, size_t inl)
 {
-       DES_cfb64_encrypt(in, out, (long)inl, ctx->cipher_data,
+       while(inl>=EVP_MAXCHUNK)
+               {
+               DES_cfb64_encrypt(in,out, (long)EVP_MAXCHUNK, ctx->cipher_data,
+                               (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
+               inl-=EVP_MAXCHUNK;
+               in +=EVP_MAXCHUNK;
+               out+=EVP_MAXCHUNK;
+               }
+       if (inl)
+               DES_cfb64_encrypt(in, out, (long)inl, ctx->cipher_data,
                          (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
        return 1;
 }
@@ -105,26 +133,45 @@ static int des_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
 /* Although we have a CFB-r implementation for DES, it doesn't pack the right
    way, so wrap it here */
 static int des_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-                          const unsigned char *in, unsigned int inl)
+                          const unsigned char *in, size_t inl)
     {
-    unsigned int n;
+    size_t n,chunk=EVP_MAXCHUNK/8;
     unsigned char c[1],d[1];
 
-    for(n=0 ; n < inl * 8; ++n)
+    if (inl<chunk) chunk=inl;
+
+    while (inl && inl>=chunk)
        {
-       c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0;
-       DES_cfb_encrypt(c,d,1,1,ctx->cipher_data,(DES_cblock *)ctx->iv,
+       for(n=0 ; n < chunk*8; ++n)
+           {
+           c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0;
+           DES_cfb_encrypt(c,d,1,1,ctx->cipher_data,(DES_cblock *)ctx->iv,
                        ctx->encrypt);
-       out[n/8]=(out[n/8]&~(0x80 >> (n%8)))|((d[0]&0x80) >> (n%8));
+           out[n/8]=(out[n/8]&~(0x80 >> (n%8)))|((d[0]&0x80) >> (n%8));
+           }
+       inl-=chunk;
+       in +=chunk;
+       out+=chunk;
+       if (inl<chunk) chunk=inl;
        }
+
     return 1;
     }
 
 static int des_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-                          const unsigned char *in, unsigned int inl)
+                          const unsigned char *in, size_t inl)
     {
-    DES_cfb_encrypt(in,out,8,inl,ctx->cipher_data,(DES_cblock *)ctx->iv,
-                   ctx->encrypt);
+    while (inl>=EVP_MAXCHUNK)
+       {
+       DES_cfb_encrypt(in,out,8,(long)EVP_MAXCHUNK,ctx->cipher_data,
+                       (DES_cblock *)ctx->iv,ctx->encrypt);
+       inl-=EVP_MAXCHUNK;
+       in +=EVP_MAXCHUNK;
+       out+=EVP_MAXCHUNK;
+       }
+    if (inl)
+       DES_cfb_encrypt(in,out,8,(long)inl,ctx->cipher_data,
+                       (DES_cblock *)ctx->iv,ctx->encrypt);
     return 1;
     }
 
index ac148ef..059ad77 100644 (file)
@@ -85,7 +85,7 @@ typedef struct
 /* Because of various casts and different args can't use IMPLEMENT_BLOCK_CIPHER */
 
 static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-                             const unsigned char *in, unsigned int inl)
+                             const unsigned char *in, size_t inl)
 {
        BLOCK_CIPHER_ecb_loop()
                DES_ecb3_encrypt((const_DES_cblock *)(in + i),
@@ -97,16 +97,27 @@ static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
 }
 
 static int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-                             const unsigned char *in, unsigned int inl)
+                             const unsigned char *in, size_t inl)
 {
-       DES_ede3_ofb64_encrypt(in, out, (long)inl,
+       if (inl>=EVP_MAXCHUNK)
+               {
+               DES_ede3_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK,
                               &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
                               (DES_cblock *)ctx->iv, &ctx->num);
+               inl-=EVP_MAXCHUNK;
+               in +=EVP_MAXCHUNK;
+               out+=EVP_MAXCHUNK;
+               }
+       if (inl)
+               DES_ede3_ofb64_encrypt(in, out, (long)inl,
+                               &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
+                               (DES_cblock *)ctx->iv, &ctx->num);
+
        return 1;
 }
 
 static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-                             const unsigned char *in, unsigned int inl)
+                             const unsigned char *in, size_t inl)
 {
 #ifdef KSSL_DEBUG
        {
@@ -119,27 +130,47 @@ static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        printf("\n");
        }
 #endif    /* KSSL_DEBUG */
-       DES_ede3_cbc_encrypt(in, out, (long)inl,
+       if (inl>=EVP_MAXCHUNK)
+               {
+               DES_ede3_cbc_encrypt(in, out, (long)EVP_MAXCHUNK,
                             &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
                             (DES_cblock *)ctx->iv, ctx->encrypt);
+               inl-=EVP_MAXCHUNK;
+               in +=EVP_MAXCHUNK;
+               out+=EVP_MAXCHUNK;
+               }
+       if (inl)
+               DES_ede3_cbc_encrypt(in, out, (long)inl,
+                            &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
+                             (DES_cblock *)ctx->iv, ctx->encrypt);
        return 1;
 }
 
 static int des_ede_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-                             const unsigned char *in, unsigned int inl)
+                             const unsigned char *in, size_t inl)
 {
-       DES_ede3_cfb64_encrypt(in, out, (long)inl, 
+       if (inl>=EVP_MAXCHUNK)
+               {
+               DES_ede3_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK, 
                               &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
                               (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
+               inl-=EVP_MAXCHUNK;
+               in +=EVP_MAXCHUNK;
+               out+=EVP_MAXCHUNK;
+               }
+       if (inl)
+               DES_ede3_cfb64_encrypt(in, out, (long)inl,
+                              &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
+                               (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
        return 1;
 }
 
 /* Although we have a CFB-r implementation for 3-DES, it doesn't pack the right
    way, so wrap it here */
 static int des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-                               const unsigned char *in, unsigned int inl)
+                               const unsigned char *in, size_t inl)
     {
-    unsigned int n;
+    size_t n;
     unsigned char c[1],d[1];
 
     for(n=0 ; n < inl ; ++n)
@@ -155,11 +186,21 @@ static int des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
     }
 
 static int des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-                               const unsigned char *in, unsigned int inl)
+                               const unsigned char *in, size_t inl)
     {
-    DES_ede3_cfb_encrypt(in,out,8,inl,
+    while (inl>=EVP_MAXCHUNK)
+       {
+       DES_ede3_cfb_encrypt(in,out,8,(long)EVP_MAXCHUNK,
                         &data(ctx)->ks1,&data(ctx)->ks2,&data(ctx)->ks3,
                         (DES_cblock *)ctx->iv,ctx->encrypt);
+       inl-=EVP_MAXCHUNK;
+       in +=EVP_MAXCHUNK;
+       out+=EVP_MAXCHUNK;
+       }
+    if (inl)
+       DES_ede3_cfb_encrypt(in,out,8,(long)inl,
+                       &data(ctx)->ks1,&data(ctx)->ks2,&data(ctx)->ks3,
+                       (DES_cblock *)ctx->iv,ctx->encrypt);
     return 1;
     }
 
index 48c33a7..806b080 100644 (file)
@@ -73,7 +73,7 @@ static int idea_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
  */
 
 static int idea_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-                          const unsigned char *in, unsigned int inl)
+                          const unsigned char *in, size_t inl)
 {
        BLOCK_CIPHER_ecb_loop()
                idea_ecb_encrypt(in + i, out + i, ctx->cipher_data);
index 5205259..7cf50e1 100644 (file)
@@ -64,7 +64,7 @@
 static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        const unsigned char *iv,int enc);
 static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-       const unsigned char *in, unsigned int inl);
+       const unsigned char *in, size_t inl);
 static const EVP_CIPHER n_cipher=
        {
        NID_undef,
@@ -93,10 +93,10 @@ static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        }
 
 static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-            const unsigned char *in, unsigned int inl)
+            const unsigned char *in, size_t inl)
        {
        if (in != out)
-               memcpy((char *)out,(const char *)in,(size_t)inl);
+               memcpy((char *)out,(const char *)in,inl);
        return 1;
        }
 
index 67af850..8b5175e 100644 (file)
@@ -78,7 +78,7 @@ typedef struct
 static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
                        const unsigned char *iv,int enc);
 static int rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-                     const unsigned char *in, unsigned int inl);
+                     const unsigned char *in, size_t inl);
 static const EVP_CIPHER r4_cipher=
        {
        NID_rc4,
@@ -128,7 +128,7 @@ static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        }
 
 static int rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-                     const unsigned char *in, unsigned int inl)
+                     const unsigned char *in, size_t inl)
        {
        RC4(&data(ctx)->ks,inl,in,out);
        return 1;
index 8832da2..250e88c 100644 (file)
 
 #include <openssl/evp.h>
 #include <openssl/objects.h>
+#include "evp_locl.h"
 #include <openssl/des.h>
 
 static int desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
                             const unsigned char *iv,int enc);
 static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-                          const unsigned char *in, unsigned int inl);
+                          const unsigned char *in, size_t inl);
 
 
 typedef struct
@@ -113,13 +114,25 @@ static int desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        }
 
 static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-                          const unsigned char *in, unsigned int inl)
+                          const unsigned char *in, size_t inl)
        {
-       DES_xcbc_encrypt(in,out,inl,&data(ctx)->ks,
+       while (inl>=EVP_MAXCHUNK)
+               {
+               DES_xcbc_encrypt(in,out,(long)EVP_MAXCHUNK,&data(ctx)->ks,
                         (DES_cblock *)&(ctx->iv[0]),
                         &data(ctx)->inw,
                         &data(ctx)->outw,
                         ctx->encrypt);
+               inl-=EVP_MAXCHUNK;
+               in +=EVP_MAXCHUNK;
+               out+=EVP_MAXCHUNK;
+               }
+       if (inl)
+               DES_xcbc_encrypt(in,out,(long)inl,&data(ctx)->ks,
+                       (DES_cblock *)&(ctx->iv[0]),
+                       &data(ctx)->inw,
+                       &data(ctx)->outw,
+                       ctx->encrypt);
        return 1;
        }
 #endif
index d1bfc9a..985ff2f 100644 (file)
@@ -299,7 +299,7 @@ struct evp_cipher_st
        int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key,
                    const unsigned char *iv, int enc);  /* init key */
        int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out,
-                        const unsigned char *in, unsigned int inl);/* encrypt/decrypt data */
+                        const unsigned char *in, size_t inl);/* encrypt/decrypt data */
        int (*cleanup)(EVP_CIPHER_CTX *); /* cleanup ctx */
        int ctx_size;           /* how big ctx->cipher_data needs to be */
        int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Populate a ASN1_TYPE with parameters */
index 0ce0124..300f4b4 100644 (file)
 /* Wrapper functions for each cipher mode */
 
 #define BLOCK_CIPHER_ecb_loop() \
-       unsigned int i, bl; \
+       size_t i, bl; \
        bl = ctx->cipher->block_size;\
        if(inl < bl) return 1;\
        inl -= bl; \
        for(i=0; i <= inl; i+=bl) 
 
 #define BLOCK_CIPHER_func_ecb(cname, cprefix, kstruct, ksched) \
-static int cname##_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \
+static int cname##_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
 {\
        BLOCK_CIPHER_ecb_loop() \
                cprefix##_ecb_encrypt(in + i, out + i, &((kstruct *)ctx->cipher_data)->ksched, ctx->encrypt);\
        return 1;\
 }
 
+#define EVP_MAXCHUNK ((size_t)1<<(sizeof(long)*8-2))
+
 #define BLOCK_CIPHER_func_ofb(cname, cprefix, cbits, kstruct, ksched) \
-static int cname##_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \
+static int cname##_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
 {\
-       cprefix##_ofb##cbits##_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\
+       while(inl>=EVP_MAXCHUNK)\
+           {\
+           cprefix##_ofb##cbits##_encrypt(in, out, (long)EVP_MAXCHUNK, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\
+           inl-=EVP_MAXCHUNK;\
+           in +=EVP_MAXCHUNK;\
+           out+=EVP_MAXCHUNK;\
+           }\
+       if (inl)\
+           cprefix##_ofb##cbits##_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\
        return 1;\
 }
 
 #define BLOCK_CIPHER_func_cbc(cname, cprefix, kstruct, ksched) \
-static int cname##_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \
+static int cname##_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
 {\
-       cprefix##_cbc_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\
+       while(inl>=EVP_MAXCHUNK) \
+           {\
+           cprefix##_cbc_encrypt(in, out, (long)EVP_MAXCHUNK, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\
+           inl-=EVP_MAXCHUNK;\
+           in +=EVP_MAXCHUNK;\
+           out+=EVP_MAXCHUNK;\
+           }\
+       if (inl)\
+           cprefix##_cbc_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\
        return 1;\
 }
 
 #define BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \
-static int cname##_cfb##cbits##_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \
+static int cname##_cfb##cbits##_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
 {\
-       cprefix##_cfb##cbits##_encrypt(in, out, (long)(cbits==1?inl*8:inl), &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num, ctx->encrypt);\
+       size_t chunk=EVP_MAXCHUNK;\
+       if (cbits==1)  chunk>>=3;\
+       if (inl<chunk) chunk=inl;\
+       while(inl && inl>=chunk)\
+           {\
+           cprefix##_cfb##cbits##_encrypt(in, out, (long)(cbits==1?chunk*8:chunk), &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num, ctx->encrypt);\
+           inl-=chunk;\
+           in +=chunk;\
+           out+=chunk;\
+           if(inl<chunk) chunk=inl;\
+           }\
        return 1;\
 }