More EVP cipher revision.
authorDr. Stephen Henson <steve@openssl.org>
Tue, 30 May 2000 18:26:22 +0000 (18:26 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Tue, 30 May 2000 18:26:22 +0000 (18:26 +0000)
Change EVP_SealInit() and EVP_OpenInit() to
handle cipher parameters.

Make it possible to set RC2 and RC5 params.

Make RC2 ASN1 code use the effective key bits
and not the key length.

TODO: document how new API works.

CHANGES
crypto/evp/e_rc2.c
crypto/evp/e_rc5.c
crypto/evp/evp.h
crypto/evp/evp_enc.c
crypto/evp/evp_err.c
crypto/evp/p_open.c
crypto/evp/p_seal.c

diff --git a/CHANGES b/CHANGES
index 34ad6c8..f50e931 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,11 +4,28 @@
 
  Changes between 0.9.5a and 0.9.6  [xx XXX 2000]
 
-  *) Remove lots of duplicated code from the EVP library. For example *every*
+  *) In ssl/s2_clnt.c and ssl/s3_clnt.c, call ERR_clear_error() when
+     the handshake is continued after ssl_verify_cert_chain();
+     otherwise, if SSL_VERIFY_NONE is set, remaining error codes
+     can lead to 'unexplainable' connection aborts later.
+     [Bodo Moeller; problem tracked down by Lutz Jaenicke]
+
+  *) Major EVP API cipher revision.
+     Add hooks for extra EVP features. This allows various cipher
+     parameters to be set in the EVP interface. Support added for variable
+     key length ciphers via the EVP_CIPHER_CTX_set_key_length() function and
+     setting of RC2 and RC5 parameters.
+
+     Modify EVP_OpenInit() and EVP_SealInit() to cope with variable key length
+     ciphers.
+
+     Remove lots of duplicated code from the EVP library. For example *every*
      cipher init() function handles the 'iv' in the same way according to the
      cipher mode. They also all do nothing if the 'key' parameter is NULL and
      for CFB and OFB modes they zero ctx->num.
 
+     New functionality allows removal of S/MIME code RC2 hack.
+
      Most of the routines have the same form and so can be declared in terms
      of macros.
 
      all individual ciphers. If the cipher wants to handle IVs or keys
      differently it can set the EVP_CIPH_CUSTOM_IV or EVP_CIPH_ALWAYS_CALL_INIT
      flags.
-     [Steve Henson]
-
-  *) In ssl/s2_clnt.c and ssl/s3_clnt.c, call ERR_clear_error() when
-     the handshake is continued after ssl_verify_cert_chain();
-     otherwise, if SSL_VERIFY_NONE is set, remaining error codes
-     can lead to 'unexplainable' connection aborts later.
-     [Bodo Moeller; problem tracked down by Lutz Jaenicke]
-
-  *) EVP cipher enhancement. Add hooks for extra EVP features. This will allow
-     various cipher parameters to be set in the EVP interface. Initially
-     support added for variable key length ciphers via the
-     EVP_CIPHER_CTX_set_key_length() function. Other cipher specific
-     parameters will be added later via the new catchall 'ctrl' function.
-     New functionality allows removal of S/MIME code RC2 hack.
-
-     Still needs support in other library functions, and allow parameter
-     setting for algorithms like RC2, RC5.
 
      Change lots of functions like EVP_EncryptUpdate() to now return a
      value: although software versions of the algorithms cannot fail
index 4c3bf1e..bf1ebbf 100644 (file)
 
 static int rc2_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key,
        unsigned char *iv,int enc);
-static int rc2_meth_to_magic(const EVP_CIPHER *e);
-static EVP_CIPHER *rc2_magic_to_meth(int i);
+static int rc2_meth_to_magic(EVP_CIPHER_CTX *ctx);
+static int rc2_magic_to_meth(int i);
 static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
 static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
 
 IMPLEMENT_BLOCK_CIPHER(rc2, rc2.ks, RC2, rc2, NID_rc2,
                        8,
                        EVP_RC2_KEY_SIZE, 8,
-                       EVP_CIPH_VARIABLE_LENGTH, rc2_init_key, NULL,
-                       rc2_set_asn1_type_and_iv, rc2_get_asn1_type_and_iv, NULL)
+                       EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
+                       rc2_init_key, NULL,
+                       rc2_set_asn1_type_and_iv, rc2_get_asn1_type_and_iv, 
+                       rc2_ctrl)
 
 #define RC2_40_MAGIC   0xa0
 #define RC2_64_MAGIC   0x78
@@ -85,7 +88,7 @@ static EVP_CIPHER r2_64_cbc_cipher=
        {
        NID_rc2_64_cbc,
        8,8 /* 64 bit */,8,
-       EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH,
+       EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
        rc2_init_key,
        rc2_cbc_cipher,
        NULL,
@@ -93,7 +96,7 @@ static EVP_CIPHER r2_64_cbc_cipher=
                sizeof((((EVP_CIPHER_CTX *)NULL)->c.rc2)),
        rc2_set_asn1_type_and_iv,
        rc2_get_asn1_type_and_iv,
-       NULL,
+       rc2_ctrl,
        NULL
        };
 
@@ -101,7 +104,7 @@ static EVP_CIPHER r2_40_cbc_cipher=
        {
        NID_rc2_40_cbc,
        8,5 /* 40 bit */,8,
-       EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH,
+       EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
        rc2_init_key,
        rc2_cbc_cipher,
        NULL,
@@ -109,7 +112,7 @@ static EVP_CIPHER r2_40_cbc_cipher=
                sizeof((((EVP_CIPHER_CTX *)NULL)->c.rc2)),
        rc2_set_asn1_type_and_iv,
        rc2_get_asn1_type_and_iv,
-       NULL,
+       rc2_ctrl,
        NULL
        };
 
@@ -127,30 +130,30 @@ static int rc2_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key,
             unsigned char *iv, int enc)
        {
        RC2_set_key(&(ctx->c.rc2.ks),EVP_CIPHER_CTX_key_length(ctx),
-                       key,EVP_CIPHER_key_length(ctx->cipher)*8);
+                       key,ctx->c.rc2.key_bits);
        return 1;
        }
 
-static int rc2_meth_to_magic(const EVP_CIPHER *e)
+static int rc2_meth_to_magic(EVP_CIPHER_CTX *e)
        {
        int i;
 
-       i=EVP_CIPHER_key_length(e);
-       if      (i == 16) return(RC2_128_MAGIC);
-       else if (i == 8)  return(RC2_64_MAGIC);
-       else if (i == 5)  return(RC2_40_MAGIC);
+       EVP_CIPHER_CTX_ctrl(e, EVP_CTRL_GET_RC2_KEY_BITS, 0, &i);
+       if      (i == 128) return(RC2_128_MAGIC);
+       else if (i == 64)  return(RC2_64_MAGIC);
+       else if (i == 40)  return(RC2_40_MAGIC);
        else return(0);
        }
 
-static EVP_CIPHER *rc2_magic_to_meth(int i)
+static int rc2_magic_to_meth(int i)
        {
-       if      (i == RC2_128_MAGIC) return(EVP_rc2_cbc());
-       else if (i == RC2_64_MAGIC)  return(EVP_rc2_64_cbc());
-       else if (i == RC2_40_MAGIC)  return(EVP_rc2_40_cbc());
+       if      (i == RC2_128_MAGIC) return 128;
+       else if (i == RC2_64_MAGIC)  return 64;
+       else if (i == RC2_40_MAGIC)  return 40;
        else
                {
                EVPerr(EVP_F_RC2_MAGIC_TO_METH,EVP_R_UNSUPPORTED_KEY_SIZE);
-               return(NULL);
+               return(0);
                }
        }
 
@@ -158,25 +161,21 @@ static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
        {
        long num=0;
        int i=0,l;
-       EVP_CIPHER *e;
+       int key_bits;
+       unsigned char iv[EVP_MAX_IV_LENGTH];
 
        if (type != NULL)
                {
                l=EVP_CIPHER_CTX_iv_length(c);
-               i=ASN1_TYPE_get_int_octetstring(type,&num,c->oiv,l);
+               i=ASN1_TYPE_get_int_octetstring(type,&num,iv,l);
                if (i != l)
                        return(-1);
-               else if (i > 0)
-                       memcpy(c->iv,c->oiv,l);
-               e=rc2_magic_to_meth((int)num);
-               if (e == NULL)
+               key_bits =rc2_magic_to_meth((int)num);
+               if (!key_bits)
                        return(-1);
-               if (e != EVP_CIPHER_CTX_cipher(c))
-                       {
-                       EVP_CIPHER_CTX_cipher(c)=e;
-                       EVP_CIPHER_CTX_set_key_length(c, EVP_CIPHER_key_length(c));
-                       rc2_init_key(c,NULL,NULL,1);
-                       }
+               if(i > 0) EVP_CipherInit(c, NULL, NULL, iv, -1);
+               EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, NULL);
+               EVP_CIPHER_CTX_set_key_length(c, key_bits / 8);
                }
        return(i);
        }
@@ -188,11 +187,36 @@ static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
 
        if (type != NULL)
                {
-               num=rc2_meth_to_magic(EVP_CIPHER_CTX_cipher(c));
+               num=rc2_meth_to_magic(c);
                j=EVP_CIPHER_CTX_iv_length(c);
                i=ASN1_TYPE_set_int_octetstring(type,num,c->oiv,j);
                }
        return(i);
        }
 
+static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+       {
+               switch(type) {
+
+                       case EVP_CTRL_INIT:
+                       c->c.rc2.key_bits = EVP_CIPHER_CTX_key_length(c) * 8;
+                       return 1;
+
+                       case EVP_CTRL_GET_RC2_KEY_BITS:
+                       *(int *)ptr = c->c.rc2.key_bits;
+                       return 1;
+                       
+                       
+                       case EVP_CTRL_SET_RC2_KEY_BITS:
+                       if(arg > 0) {
+                               c->c.rc2.key_bits = arg;
+                               return 1;
+                       }
+                       return 0;
+
+                       default:
+                       return -1;
+               }
+       }
+
 #endif
index 3998e0c..668b217 100644 (file)
 
 static int r_32_12_16_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key,
        unsigned char *iv,int enc);
+static int rc5_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
 
 IMPLEMENT_BLOCK_CIPHER(rc5_32_12_16, rc5.ks, RC5_32, rc5, NID_rc5,
                        8, EVP_RC5_32_12_16_KEY_SIZE, 8, 
-                       0, r_32_12_16_init_key, NULL,
-                       NULL, NULL, NULL)
+                       EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
+                       r_32_12_16_init_key, NULL,
+                       NULL, NULL, rc5_ctrl)
+
 
-#if 0
-static int r_32_12_16_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-       unsigned char *in, unsigned int inl);
-static EVP_CIPHER rc5_32_12_16_cbc_cipher=
-       {
-       NID_rc5_cbc,
-       8,EVP_RC5_32_12_16_KEY_SIZE,8,
-       EVP_CIPH_CBC_MODE,
-       r_32_12_16_cbc_init_key,
-       r_32_12_16_cbc_cipher,
-       NULL,
-       sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+
-               sizeof((((EVP_CIPHER_CTX *)NULL)->c.rc5)),
-       NULL,
-       NULL,
-       NULL
-       };
 
-EVP_CIPHER *EVP_rc5_32_12_16_cbc(void)
+static int rc5_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
        {
-       return(&rc5_32_12_16_cbc_cipher);
+               switch(type) {
+
+                       case EVP_CTRL_INIT:
+                       c->c.rc5.rounds = RC5_12_ROUNDS;
+                       return 1;
+
+                       case EVP_CTRL_GET_RC5_ROUNDS:
+                       *(int *)ptr = c->c.rc5.rounds;
+                       return 1;
+                       
+                       
+                       case EVP_CTRL_SET_RC5_ROUNDS:
+                       switch(arg) {
+                               case RC5_8_ROUNDS:
+                               case RC5_12_ROUNDS:
+                               case RC5_16_ROUNDS:
+                               c->c.rc5.rounds = arg;
+                               return 1;
+
+                               default:
+                               EVPerr(EVP_F_RC5_CTRL, EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS);
+                               return 0;
+                       }
+
+                       default:
+                       return -1;
+               }
        }
-#endif
-       
+
 static int r_32_12_16_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key,
             unsigned char *iv, int enc)
        {
-       RC5_32_set_key(&(ctx->c.rc5.ks),EVP_RC5_32_12_16_KEY_SIZE,
-                       key,RC5_12_ROUNDS);
-       return 1;
-       }
-#if 0
-static int r_32_12_16_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-            unsigned char *in, unsigned int inl)
-       {
-       RC5_32_cbc_encrypt(
-               in,out,(long)inl,
-               &(ctx->c.rc5.ks),&(ctx->iv[0]),
-               ctx->encrypt);
+       RC5_32_set_key(&(ctx->c.rc5.ks),EVP_CIPHER_CTX_key_length(ctx),
+                       key,ctx->c.rc5.rounds);
        return 1;
        }
-#endif
 
 #endif
index abb1490..7db80c3 100644 (file)
@@ -589,6 +589,7 @@ void        ERR_load_EVP_strings(void );
 void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a);
 int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a);
 int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen);
+int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr);
 
 #ifdef HEADER_BIO_H
 BIO_METHOD *BIO_f_md(void);
@@ -738,6 +739,7 @@ void EVP_PBE_cleanup(void);
 /* Function codes. */
 #define EVP_F_D2I_PKEY                                  100
 #define EVP_F_EVP_CIPHERINIT                            123
+#define EVP_F_EVP_CIPHER_CTX_CTRL                       124
 #define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH             122
 #define EVP_F_EVP_DECRYPTFINAL                          101
 #define EVP_F_EVP_MD_CTX_COPY                           110
@@ -759,12 +761,15 @@ void EVP_PBE_cleanup(void);
 #define EVP_F_PKCS5_PBE_KEYIVGEN                        117
 #define EVP_F_PKCS5_V2_PBE_KEYIVGEN                     118
 #define EVP_F_RC2_MAGIC_TO_METH                                 109
+#define EVP_F_RC5_CTRL                                  125
 
 /* Reason codes. */
 #define EVP_R_BAD_DECRYPT                               100
 #define EVP_R_BN_DECODE_ERROR                           112
 #define EVP_R_BN_PUBKEY_ERROR                           113
 #define EVP_R_CIPHER_PARAMETER_ERROR                    122
+#define EVP_R_CTRL_NOT_IMPLEMENTED                      132
+#define EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED            133
 #define EVP_R_DECODE_ERROR                              114
 #define EVP_R_DIFFERENT_KEY_TYPES                       101
 #define EVP_R_ENCODE_ERROR                              115
@@ -772,6 +777,7 @@ void EVP_PBE_cleanup(void);
 #define EVP_R_EXPECTING_AN_RSA_KEY                      127
 #define EVP_R_EXPECTING_A_DH_KEY                        128
 #define EVP_R_EXPECTING_A_DSA_KEY                       129
+#define EVP_R_INITIALIZATION_ERROR                      134
 #define EVP_R_INPUT_NOT_INITIALIZED                     111
 #define EVP_R_INVALID_KEY_LENGTH                        130
 #define EVP_R_IV_TOO_LARGE                              102
@@ -784,6 +790,7 @@ void EVP_PBE_cleanup(void);
 #define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE                         117
 #define EVP_R_PUBLIC_KEY_NOT_RSA                        106
 #define EVP_R_UNKNOWN_PBE_ALGORITHM                     121
+#define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS               135
 #define EVP_R_UNSUPPORTED_CIPHER                        107
 #define EVP_R_UNSUPPORTED_KEYLENGTH                     123
 #define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION       124
index 4bf3a56..e2687f9 100644 (file)
@@ -73,10 +73,16 @@ void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
 int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
             unsigned char *key, unsigned char *iv, int enc)
        {
-       if(enc) enc = 1;
+       if(enc && (enc != -1)) enc = 1;
        if (cipher) {
                ctx->cipher=cipher;
                ctx->key_len = cipher->key_len;
+               if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT) {
+                       if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) {
+                               EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_INITIALIZATION_ERROR);
+                               return 0;
+                       }
+               }
        } else if(!ctx->cipher) {
                EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_NO_CIPHER_SET);
                return 0;
@@ -108,7 +114,7 @@ int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
        if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) {
                if(!ctx->cipher->init(ctx,key,iv,enc)) return 0;
        }
-       ctx->encrypt=enc;
+       if(enc != -1) ctx->encrypt=enc;
        ctx->buf_len=0;
        return 1;
        }
@@ -301,6 +307,8 @@ int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
 
 int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
        {
+       if(c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH) 
+               return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, keylen, NULL);
        if(c->key_len == keylen) return 1;
        if((keylen > 0) && (c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH))
                {
@@ -310,3 +318,24 @@ int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
        EVPerr(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH,EVP_R_INVALID_KEY_LENGTH);
        return 0;
        }
+
+int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
+{
+       int ret;
+       if(!ctx->cipher) {
+               EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET);
+               return 0;
+       }
+
+       if(!ctx->cipher->ctrl) {
+               EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED);
+               return 0;
+       }
+
+       ret = ctx->cipher->ctrl(ctx, type, arg, ptr);
+       if(ret == -1) {
+               EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED);
+               return 0;
+       }
+       return ret;
+}
index d48d944..a01412a 100644 (file)
@@ -68,6 +68,7 @@ static ERR_STRING_DATA EVP_str_functs[]=
        {
 {ERR_PACK(0,EVP_F_D2I_PKEY,0), "D2I_PKEY"},
 {ERR_PACK(0,EVP_F_EVP_CIPHERINIT,0),   "EVP_CipherInit"},
+{ERR_PACK(0,EVP_F_EVP_CIPHER_CTX_CTRL,0),      "EVP_CIPHER_CTX_ctrl"},
 {ERR_PACK(0,EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH,0),    "EVP_CIPHER_CTX_set_key_length"},
 {ERR_PACK(0,EVP_F_EVP_DECRYPTFINAL,0), "EVP_DecryptFinal"},
 {ERR_PACK(0,EVP_F_EVP_MD_CTX_COPY,0),  "EVP_MD_CTX_copy"},
@@ -89,6 +90,7 @@ static ERR_STRING_DATA EVP_str_functs[]=
 {ERR_PACK(0,EVP_F_PKCS5_PBE_KEYIVGEN,0),       "PKCS5_PBE_keyivgen"},
 {ERR_PACK(0,EVP_F_PKCS5_V2_PBE_KEYIVGEN,0),    "PKCS5_v2_PBE_keyivgen"},
 {ERR_PACK(0,EVP_F_RC2_MAGIC_TO_METH,0),        "RC2_MAGIC_TO_METH"},
+{ERR_PACK(0,EVP_F_RC5_CTRL,0), "RC5_CTRL"},
 {0,NULL}
        };
 
@@ -98,6 +100,8 @@ static ERR_STRING_DATA EVP_str_reasons[]=
 {EVP_R_BN_DECODE_ERROR                   ,"bn decode error"},
 {EVP_R_BN_PUBKEY_ERROR                   ,"bn pubkey error"},
 {EVP_R_CIPHER_PARAMETER_ERROR            ,"cipher parameter error"},
+{EVP_R_CTRL_NOT_IMPLEMENTED              ,"ctrl not implemented"},
+{EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED    ,"ctrl operation not implemented"},
 {EVP_R_DECODE_ERROR                      ,"decode error"},
 {EVP_R_DIFFERENT_KEY_TYPES               ,"different key types"},
 {EVP_R_ENCODE_ERROR                      ,"encode error"},
@@ -105,6 +109,7 @@ static ERR_STRING_DATA EVP_str_reasons[]=
 {EVP_R_EXPECTING_AN_RSA_KEY              ,"expecting an rsa key"},
 {EVP_R_EXPECTING_A_DH_KEY                ,"expecting a dh key"},
 {EVP_R_EXPECTING_A_DSA_KEY               ,"expecting a dsa key"},
+{EVP_R_INITIALIZATION_ERROR              ,"initialization error"},
 {EVP_R_INPUT_NOT_INITIALIZED             ,"input not initialized"},
 {EVP_R_INVALID_KEY_LENGTH                ,"invalid key length"},
 {EVP_R_IV_TOO_LARGE                      ,"iv too large"},
@@ -117,6 +122,7 @@ static ERR_STRING_DATA EVP_str_reasons[]=
 {EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE         ,"pkcs8 unknown broken type"},
 {EVP_R_PUBLIC_KEY_NOT_RSA                ,"public key not rsa"},
 {EVP_R_UNKNOWN_PBE_ALGORITHM             ,"unknown pbe algorithm"},
+{EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS       ,"unsuported number of rounds"},
 {EVP_R_UNSUPPORTED_CIPHER                ,"unsupported cipher"},
 {EVP_R_UNSUPPORTED_KEYLENGTH             ,"unsupported keylength"},
 {EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION,"unsupported key derivation function"},
index b9ca789..6dbccce 100644 (file)
@@ -76,6 +76,11 @@ int EVP_OpenInit(EVP_CIPHER_CTX *ctx, EVP_CIPHER *type, unsigned char *ek,
                goto err;
                 }
 
+       if(type) {      
+               EVP_CIPHER_CTX_init(ctx);
+               EVP_DecryptInit(ctx,type,NULL,NULL);
+       }
+
        size=RSA_size(priv->pkey.rsa);
        key=(unsigned char *)Malloc(size+2);
        if (key == NULL)
@@ -87,14 +92,13 @@ int EVP_OpenInit(EVP_CIPHER_CTX *ctx, EVP_CIPHER *type, unsigned char *ek,
                }
 
        i=EVP_PKEY_decrypt(key,ek,ekl,priv);
-       if (i != type->key_len)
+       if ((i <= 0) || !EVP_CIPHER_CTX_set_key_length(ctx, i))
                {
                /* ERROR */
                goto err;
                }
+       if(!EVP_DecryptInit(ctx,NULL,key,iv)) goto err;
 
-       EVP_CIPHER_CTX_init(ctx);
-       EVP_DecryptInit(ctx,type,key,iv);
        ret=1;
 err:
        if (key != NULL) memset(key,0,size);
index d449e89..47efc0d 100644 (file)
@@ -73,17 +73,20 @@ int EVP_SealInit(EVP_CIPHER_CTX *ctx, EVP_CIPHER *type, unsigned char **ek,
        int i;
        
        if (npubk <= 0) return(0);
+       if(type) {
+               EVP_CIPHER_CTX_init(ctx);
+               EVP_EncryptInit(ctx,type,NULL,NULL);
+       }
        if (RAND_bytes(key,EVP_MAX_KEY_LENGTH) <= 0)
                return(0);
-       if (type->iv_len > 0)
-               RAND_pseudo_bytes(iv,type->iv_len);
+       if (EVP_CIPHER_CTX_iv_length(ctx))
+               RAND_pseudo_bytes(iv,EVP_CIPHER_CTX_iv_length(ctx));
 
-       EVP_CIPHER_CTX_init(ctx);
-       EVP_EncryptInit(ctx,type,key,iv);
+       if(!EVP_EncryptInit(ctx,NULL,key,iv)) return 0;
 
        for (i=0; i<npubk; i++)
                {
-               ekl[i]=EVP_PKEY_encrypt(ek[i],key,EVP_CIPHER_key_length(type),
+               ekl[i]=EVP_PKEY_encrypt(ek[i],key,EVP_CIPHER_CTX_key_length(ctx),
                        pubk[i]);
                if (ekl[i] <= 0) return(-1);
                }