From 49528751b878a8198f628dff6651e4547818a2cf Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Tue, 30 May 2000 18:26:22 +0000 Subject: [PATCH] More EVP cipher revision. 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 | 36 +++++++++--------- crypto/evp/e_rc2.c | 88 ++++++++++++++++++++++++++++---------------- crypto/evp/e_rc5.c | 72 ++++++++++++++++++------------------ crypto/evp/evp.h | 7 ++++ crypto/evp/evp_enc.c | 33 ++++++++++++++++- crypto/evp/evp_err.c | 6 +++ crypto/evp/p_open.c | 10 +++-- crypto/evp/p_seal.c | 13 ++++--- 8 files changed, 169 insertions(+), 96 deletions(-) diff --git a/CHANGES b/CHANGES index 34ad6c80b8..f50e93153a 100644 --- 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. @@ -16,23 +33,6 @@ 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 diff --git a/crypto/evp/e_rc2.c b/crypto/evp/e_rc2.c index 4c3bf1e649..bf1ebbf2c9 100644 --- a/crypto/evp/e_rc2.c +++ b/crypto/evp/e_rc2.c @@ -66,16 +66,19 @@ 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 diff --git a/crypto/evp/e_rc5.c b/crypto/evp/e_rc5.c index 3998e0c6c8..668b21756a 100644 --- a/crypto/evp/e_rc5.c +++ b/crypto/evp/e_rc5.c @@ -66,53 +66,53 @@ 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 diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h index abb1490b81..7db80c3d52 100644 --- a/crypto/evp/evp.h +++ b/crypto/evp/evp.h @@ -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 diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c index 4bf3a565a7..e2687f9879 100644 --- a/crypto/evp/evp_enc.c +++ b/crypto/evp/evp_enc.c @@ -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; +} diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c index d48d9442b2..a01412a07c 100644 --- a/crypto/evp/evp_err.c +++ b/crypto/evp/evp_err.c @@ -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"}, diff --git a/crypto/evp/p_open.c b/crypto/evp/p_open.c index b9ca7892c2..6dbccceafa 100644 --- a/crypto/evp/p_open.c +++ b/crypto/evp/p_open.c @@ -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); diff --git a/crypto/evp/p_seal.c b/crypto/evp/p_seal.c index d449e892bf..47efc0d3d8 100644 --- a/crypto/evp/p_seal.c +++ b/crypto/evp/p_seal.c @@ -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