mirror of
https://github.com/openssl/openssl.git
synced 2025-01-18 13:44:20 +08:00
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.
This commit is contained in:
parent
547bf7f983
commit
49528751b8
36
CHANGES
36
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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
RC5_32_set_key(&(ctx->c.rc5.ks),EVP_CIPHER_CTX_key_length(ctx),
|
||||
key,ctx->c.rc5.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);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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"},
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user