enhance and tidy up the EVP interface.
This patch adds initial support for variable length ciphers
and changes S/MIME code to use this.
Some other library functions need modifying to support use
of modified cipher parameters.
Also need to change all the cipher functions that should
return error codes, but currenly don't.
And of course it needs extensive testing...
Changes between 0.9.5a and 0.9.6 [xx XXX 2000]
+ *) EVP cipher enhancment. 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, also need to add return codes to
+ some EVP functions.
+ [Steve Henson]
+
*) Implement SSL_OP_TLS_ROLLBACK_BUG: In ssl3_get_client_key_exchange, if
this option is set, tolerate broken clients that send the negotiated
protocol version number instead of the requested protocol version
OpenSSL STATUS Last modified at
- ______________ $Date: 2000/04/14 23:35:50 $
+ ______________ $Date: 2000/05/26 23:51:09 $
DEVELOPMENT STATE
IN PROGRESS
o Steve is currently working on (in no particular order):
+ EVP cipher enhancement.
Proper (or at least usable) certificate chain verification.
Private key, certificate and CRL API and implementation.
Developing and bugfixing PKCS#7 (S/MIME code).
Various X509 issues: character sets, certificate request extensions.
- Documentation for the openssl utility.
NEEDS PATCH
to date.
Paul +1
- o The EVP and ASN1 stuff is a mess. Currently you have one EVP_CIPHER
- structure for each cipher. This may make sense for things like DES but
- for variable length ciphers like RC2 and RC4 it is NBG. Need a way to
- use the EVP interface and set up the cipher parameters. The ASN1 stuff
- is also foo wrt ciphers whose AlgorithmIdentifier has more than just
- an IV in it (e.g. RC2, RC5). This also means that EVP_Seal and EVP_Open
- don't work unless the key length matches the fixed value (some vendors
- use a key length decided by the size of the RSA encrypted key and expect
- RC2 to adapt).
-
WISHES
o
{
NID_des_ede_cbc,
8,16,8,
+ EVP_CIPH_CBC_MODE,
des_cbc_ede_init_key,
des_cbc_ede_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.des_ede)),
EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv,
+ NULL
};
static EVP_CIPHER d_cbc_ede_cipher3=
{
NID_des_ede3_cbc,
8,24,8,
+ EVP_CIPH_CBC_MODE,
des_cbc_ede3_init_key,
des_cbc_ede_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.des_ede)),
EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv,
+ NULL
};
EVP_CIPHER *EVP_des_ede_cbc(void)
{
NID_bf_cbc,
8,EVP_BLOWFISH_KEY_SIZE,8,
+ EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH,
bf_cbc_init_key,
bf_cbc_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.bf_ks)),
EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv,
+ NULL
};
EVP_CIPHER *EVP_bf_cbc(void)
memcpy(&(ctx->oiv[0]),iv,8);
memcpy(&(ctx->iv[0]),&(ctx->oiv[0]),8);
if (key != NULL)
- BF_set_key(&(ctx->c.bf_ks),EVP_BLOWFISH_KEY_SIZE,key);
+ BF_set_key(&(ctx->c.bf_ks),EVP_CIPHER_CTX_key_length(ctx),key);
}
static void bf_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
{
NID_cast5_cbc,
8,EVP_CAST5_KEY_SIZE,8,
+ EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH,
cast_cbc_init_key,
cast_cbc_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.cast_ks)),
EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv,
+ NULL
};
EVP_CIPHER *EVP_cast5_cbc(void)
memcpy(&(ctx->oiv[0]),iv,8);
memcpy(&(ctx->iv[0]),&(ctx->oiv[0]),8);
if (key != NULL)
- CAST_set_key(&(ctx->c.cast_ks),EVP_CAST5_KEY_SIZE,key);
+ CAST_set_key(&(ctx->c.cast_ks),EVP_CIPHER_CTX_key_length(ctx),key);
}
static void cast_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
{
NID_des_cbc,
8,8,8,
+ EVP_CIPH_CBC_MODE,
des_cbc_init_key,
des_cbc_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.des_ks)),
EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv,
+ NULL
};
EVP_CIPHER *EVP_des_cbc(void)
{
NID_idea_cbc,
8,16,8,
+ EVP_CIPH_CBC_MODE,
idea_cbc_init_key,
idea_cbc_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.idea_ks)),
EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv,
+ NULL
};
EVP_CIPHER *EVP_idea_cbc(void)
{
NID_rc2_cbc,
8,EVP_RC2_KEY_SIZE,8,
+ EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH,
rc2_cbc_init_key,
rc2_cbc_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.rc2_ks)),
rc2_set_asn1_type_and_iv,
rc2_get_asn1_type_and_iv,
+ NULL
};
static EVP_CIPHER r2_64_cbc_cipher=
{
NID_rc2_64_cbc,
8,8 /* 64 bit */,8,
+ EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH,
rc2_cbc_init_key,
rc2_cbc_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.rc2_ks)),
rc2_set_asn1_type_and_iv,
rc2_get_asn1_type_and_iv,
+ NULL
};
static EVP_CIPHER r2_40_cbc_cipher=
{
NID_rc2_40_cbc,
8,5 /* 40 bit */,8,
+ EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH,
rc2_cbc_init_key,
rc2_cbc_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.rc2_ks)),
rc2_set_asn1_type_and_iv,
rc2_get_asn1_type_and_iv,
+ NULL
};
EVP_CIPHER *EVP_rc2_cbc(void)
memcpy(&(ctx->iv[0]),&(ctx->oiv[0]),8);
if (key != NULL)
RC2_set_key(&(ctx->c.rc2_ks),EVP_CIPHER_CTX_key_length(ctx),
- key,EVP_CIPHER_CTX_key_length(ctx)*8);
+ key,EVP_CIPHER_key_length(ctx->cipher)*8);
}
static void rc2_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
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_cbc_init_key(c,NULL,NULL,1);
}
}
{
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 *)NULL)->c.rc5_ks)),
NULL,
NULL,
+ NULL
};
EVP_CIPHER *EVP_rc5_32_12_16_cbc(void)
{
NID_des_ede_cfb64,
1,16,8,
+ EVP_CIPH_CFB_MODE,
des_ede_cfb_init_key,
des_ede_cfb_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.des_ede)),
EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv,
+ NULL
};
static EVP_CIPHER d_ede3_cfb_cipher3=
{
NID_des_ede3_cfb64,
1,24,8,
+ EVP_CIPH_CFB_MODE,
des_ede3_cfb_init_key,
des_ede_cfb_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.des_ede)),
EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv,
+ NULL
};
EVP_CIPHER *EVP_des_ede_cfb(void)
{
NID_bf_cfb64,
1,EVP_BLOWFISH_KEY_SIZE,8,
+ EVP_CIPH_CFB_MODE | EVP_CIPH_VARIABLE_LENGTH,
bf_cfb_init_key,
bf_cfb_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.bf_ks)),
EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv,
+ NULL
};
EVP_CIPHER *EVP_bf_cfb(void)
memcpy(&(ctx->oiv[0]),iv,8);
memcpy(&(ctx->iv[0]),&(ctx->oiv[0]),8);
if (key != NULL)
- BF_set_key(&(ctx->c.bf_ks),EVP_BLOWFISH_KEY_SIZE,key);
+ BF_set_key(&(ctx->c.bf_ks),EVP_CIPHER_CTX_key_length(ctx),key);
}
static void bf_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
{
NID_cast5_cfb64,
1,EVP_CAST5_KEY_SIZE,8,
+ EVP_CIPH_CFB_MODE | EVP_CIPH_VARIABLE_LENGTH,
cast_cfb_init_key,
cast_cfb_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.cast_ks)),
EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv,
+ NULL
};
EVP_CIPHER *EVP_cast5_cfb(void)
memcpy(&(ctx->oiv[0]),iv,8);
memcpy(&(ctx->iv[0]),&(ctx->oiv[0]),8);
if (key != NULL)
- CAST_set_key(&(ctx->c.cast_ks),EVP_CAST5_KEY_SIZE,key);
+ CAST_set_key(&(ctx->c.cast_ks),EVP_CIPHER_CTX_key_length(ctx),key);
}
static void cast_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
{
NID_des_cfb64,
1,8,8,
+ EVP_CIPH_CFB_MODE,
des_cfb_init_key,
des_cfb_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.des_ks)),
EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv,
+ NULL
};
EVP_CIPHER *EVP_des_cfb(void)
{
NID_idea_cfb64,
1,IDEA_KEY_LENGTH,IDEA_BLOCK,
+ EVP_CIPH_CFB_MODE,
idea_cfb_init_key,
idea_cfb_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.idea_ks)),
EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv,
+ NULL
};
EVP_CIPHER *EVP_idea_cfb(void)
{
NID_rc2_cfb64,
1,EVP_RC2_KEY_SIZE,8,
+ EVP_CIPH_CFB_MODE | EVP_CIPH_VARIABLE_LENGTH,
rc2_cfb_init_key,
rc2_cfb_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.rc2_ks)),
EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv,
+ NULL
};
EVP_CIPHER *EVP_rc2_cfb(void)
memcpy(&(ctx->iv[0]),&(ctx->oiv[0]),8);
if (key != NULL)
RC2_set_key(&(ctx->c.rc2_ks),EVP_CIPHER_CTX_key_length(ctx),
- key,EVP_CIPHER_CTX_key_length(ctx)*8);
+ key,EVP_CIPHER_key_length(ctx->cipher)*8);
}
static void rc2_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
{
NID_rc5_cfb64,
1,EVP_RC5_32_12_16_KEY_SIZE,8,
+ EVP_CIPH_CFB_MODE,
rc5_32_12_16_cfb_init_key,
rc5_32_12_16_cfb_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.rc5_ks)),
EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv,
+ NULL
};
EVP_CIPHER *EVP_rc5_32_12_16_cfb(void)
{
NID_des_ede,
8,16,0,
+ EVP_CIPH_ECB_MODE,
des_ede_init_key,
des_ede_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.des_ede)),
NULL,
NULL,
+ NULL
};
static EVP_CIPHER d_ede3_cipher3=
{
NID_des_ede3,
8,24,0,
+ EVP_CIPH_ECB_MODE,
des_ede3_init_key,
des_ede_cipher,
NULL,
sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+
sizeof((((EVP_CIPHER_CTX *)NULL)->c.des_ede)),
NULL,
+ NULL,
+ NULL
};
EVP_CIPHER *EVP_des_ede(void)
{
NID_bf_ecb,
8,EVP_BLOWFISH_KEY_SIZE,0,
+ EVP_CIPH_ECB_MODE | EVP_CIPH_VARIABLE_LENGTH,
bf_ecb_init_key,
bf_ecb_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.bf_ks)),
NULL,
NULL,
+ NULL
};
EVP_CIPHER *EVP_bf_ecb(void)
unsigned char *iv, int enc)
{
if (key != NULL)
- BF_set_key(&(ctx->c.bf_ks),EVP_BLOWFISH_KEY_SIZE,key);
+ BF_set_key(&(ctx->c.bf_ks),EVP_CIPHER_CTX_key_length(ctx),key);
}
static void bf_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
{
NID_cast5_ecb,
8,EVP_CAST5_KEY_SIZE,0,
+ EVP_CIPH_ECB_MODE | EVP_CIPH_VARIABLE_LENGTH,
cast_ecb_init_key,
cast_ecb_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.cast_ks)),
NULL,
NULL,
+ NULL
};
EVP_CIPHER *EVP_cast5_ecb(void)
unsigned char *iv, int enc)
{
if (key != NULL)
- CAST_set_key(&(ctx->c.cast_ks),EVP_CAST5_KEY_SIZE,key);
+ CAST_set_key(&(ctx->c.cast_ks),EVP_CIPHER_CTX_key_length(ctx),key);
}
static void cast_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
{
NID_des_ecb,
8,8,0,
+ EVP_CIPH_ECB_MODE,
des_ecb_init_key,
des_ecb_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.des_ks)),
NULL,
NULL,
+ NULL
};
EVP_CIPHER *EVP_des_ecb(void)
{
NID_idea_ecb,
8,16,0,
+ EVP_CIPH_ECB_MODE,
idea_ecb_init_key,
idea_ecb_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.idea_ks)),
NULL,
NULL,
+ NULL
};
EVP_CIPHER *EVP_idea_ecb(void)
{
NID_rc2_ecb,
8,EVP_RC2_KEY_SIZE,0,
+ EVP_CIPH_ECB_MODE | EVP_CIPH_VARIABLE_LENGTH,
rc2_ecb_init_key,
rc2_ecb_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.rc2_ks)),
NULL,
NULL,
+ NULL
};
EVP_CIPHER *EVP_rc2_ecb(void)
{
if (key != NULL)
RC2_set_key(&(ctx->c.rc2_ks),EVP_CIPHER_CTX_key_length(ctx),
- key,EVP_CIPHER_CTX_key_length(ctx)*8);
+ key,EVP_CIPHER_key_length(ctx->cipher)*8);
}
static void rc2_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
{
NID_rc5_ecb,
8,EVP_RC5_32_12_16_KEY_SIZE,0,
+ EVP_CIPH_ECB_MODE,
rc5_32_12_16_ecb_init_key,
rc5_32_12_16_ecb_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.rc5_ks)),
NULL,
NULL,
+ NULL
};
EVP_CIPHER *EVP_rc5_32_12_16_ecb(void)
{
NID_undef,
1,0,0,
+ 0,
null_init_key,
null_cipher,
NULL,
0,
NULL,
NULL,
+ NULL
};
EVP_CIPHER *EVP_enc_null(void)
{
NID_des_ede_ofb64,
1,16,8,
+ EVP_CIPH_OFB_MODE,
des_ede_ofb_init_key,
des_ede_ofb_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.des_ede)),
EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv,
+ NULL
};
static EVP_CIPHER d_ede3_ofb_cipher3=
{
NID_des_ede3_ofb64,
1,24,8,
+ EVP_CIPH_OFB_MODE,
des_ede3_ofb_init_key,
des_ede_ofb_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.des_ede)),
EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv,
+ NULL
};
EVP_CIPHER *EVP_des_ede_ofb(void)
{
NID_bf_ofb64,
1,EVP_BLOWFISH_KEY_SIZE,8,
+ EVP_CIPH_OFB_MODE | EVP_CIPH_VARIABLE_LENGTH,
bf_ofb_init_key,
bf_ofb_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.bf_ks)),
EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv,
+ NULL
};
EVP_CIPHER *EVP_bf_ofb(void)
memcpy(&(ctx->oiv[0]),iv,8);
memcpy(&(ctx->iv[0]),&(ctx->oiv[0]),8);
if (key != NULL)
- BF_set_key(&(ctx->c.bf_ks),EVP_BLOWFISH_KEY_SIZE,key);
+ BF_set_key(&(ctx->c.bf_ks),EVP_CIPHER_CTX_key_length(ctx),key);
}
static void bf_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
{
NID_cast5_ofb64,
1,EVP_CAST5_KEY_SIZE,8,
+ EVP_CIPH_OFB_MODE | EVP_CIPH_VARIABLE_LENGTH,
cast_ofb_init_key,
cast_ofb_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.cast_ks)),
EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv,
+ NULL
};
EVP_CIPHER *EVP_cast5_ofb(void)
memcpy(&(ctx->oiv[0]),iv,8);
memcpy(&(ctx->iv[0]),&(ctx->oiv[0]),8);
if (key != NULL)
- CAST_set_key(&(ctx->c.cast_ks),EVP_CAST5_KEY_SIZE,key);
+ CAST_set_key(&(ctx->c.cast_ks),EVP_CIPHER_CTX_key_length(ctx),key);
}
static void cast_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
{
NID_des_ofb64,
1,8,8,
+ EVP_CIPH_OFB_MODE,
des_ofb_init_key,
des_ofb_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.des_ks)),
EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv,
+ NULL
};
EVP_CIPHER *EVP_des_ofb(void)
{
NID_idea_ofb64,
1,IDEA_KEY_LENGTH,IDEA_BLOCK,
+ EVP_CIPH_OFB_MODE,
idea_ofb_init_key,
idea_ofb_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.idea_ks)),
EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv,
+ NULL
};
EVP_CIPHER *EVP_idea_ofb(void)
{
NID_rc2_ofb64,
1,EVP_RC2_KEY_SIZE,8,
+ EVP_CIPH_OFB_MODE | EVP_CIPH_VARIABLE_LENGTH,
rc2_ofb_init_key,
rc2_ofb_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.rc2_ks)),
EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv,
+ NULL
};
EVP_CIPHER *EVP_rc2_ofb(void)
memcpy(&(ctx->iv[0]),&(ctx->oiv[0]),8);
if (key != NULL)
RC2_set_key(&(ctx->c.rc2_ks),EVP_CIPHER_CTX_key_length(ctx),
- key,EVP_CIPHER_CTX_key_length(ctx)*8);
+ key,EVP_CIPHER_key_length(ctx->cipher)*8);
}
static void rc2_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
{
NID_rc5_ofb64,
1,EVP_RC5_32_12_16_KEY_SIZE,8,
+ EVP_CIPH_OFB_MODE,
rc5_32_12_16_ofb_init_key,
rc5_32_12_16_ofb_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.rc5_ks)),
EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv,
+ NULL
};
EVP_CIPHER *EVP_rc5_32_12_16_ofb(void)
{
NID_rc4,
1,EVP_RC4_KEY_SIZE,0,
+ EVP_CIPH_VARIABLE_LENGTH,
rc4_init_key,
rc4_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.rc4)),
NULL,
NULL,
+ NULL
};
static EVP_CIPHER r4_40_cipher=
{
NID_rc4_40,
1,5 /* 40 bit */,0,
+ EVP_CIPH_VARIABLE_LENGTH,
rc4_init_key,
rc4_cipher,
+ NULL,
+ sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+
+ sizeof((((EVP_CIPHER_CTX *)NULL)->c.rc4)),
+ NULL,
+ NULL,
+ NULL
};
EVP_CIPHER *EVP_rc4(void)
{
NID_desx_cbc,
8,24,8,
+ EVP_CIPH_CBC_MODE,
desx_cbc_init_key,
desx_cbc_cipher,
NULL,
sizeof((((EVP_CIPHER_CTX *)NULL)->c.desx_cbc)),
EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv,
+ NULL
};
EVP_CIPHER *EVP_desx_cbc(void)
} md;
} EVP_MD_CTX;
-typedef struct evp_cipher_st
+typedef struct evp_cipher_st EVP_CIPHER;
+typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX;
+
+struct evp_cipher_st
{
int nid;
int block_size;
- int key_len;
+ int key_len; /* Default value for variable length ciphers */
int iv_len;
- void (*init)(); /* init for encryption */
- void (*do_cipher)(); /* encrypt data */
- void (*cleanup)(); /* used by cipher method */
+ unsigned long flags; /* Various flags */
+ void (*init)(EVP_CIPHER_CTX *, unsigned char *, unsigned char *, int); /* init key */
+ void (*do_cipher)(EVP_CIPHER_CTX *, unsigned char *, unsigned char *, unsigned int);/* encrypt/decrypt data */
+ void (*cleanup)(EVP_CIPHER_CTX *); /* cleanup ctx */
int ctx_size; /* how big the ctx needs to be */
- /* int set_asn1_parameters(EVP_CIPHER_CTX,ASN1_TYPE *); */
- int (*set_asn1_parameters)(); /* Populate a ASN1_TYPE with parameters */
- /* int get_asn1_parameters(EVP_CIPHER_CTX,ASN1_TYPE *); */
- int (*get_asn1_parameters)(); /* Get parameters from a ASN1_TYPE */
- } EVP_CIPHER;
+ int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Populate a ASN1_TYPE with parameters */
+ int (*get_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Get parameters from a ASN1_TYPE */
+ int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr); /* Miscellaneous operations */
+ };
+
+/* Values for cipher flags */
+
+/* Modes for block ciphers */
+
+#define EVP_CIPH_ECB_MODE 0x1
+#define EVP_CIPH_CBC_MODE 0x2
+#define EVP_CIPH_CFB_MODE 0x3
+#define EVP_CIPH_OFB_MODE 0x4
+#define EVP_CIPH_BLOCK_MODES 0x7
+/* Set if variable length cipher */
+#define EVP_CIPH_VARIABLE_LENGTH 0x8
+
typedef struct evp_cipher_info_st
{
unsigned char iv[EVP_MAX_IV_LENGTH];
} EVP_CIPHER_INFO;
-typedef struct evp_cipher_ctx_st
+struct evp_cipher_ctx_st
{
const EVP_CIPHER *cipher;
int encrypt; /* encrypt or decrypt */
unsigned char buf[EVP_MAX_IV_LENGTH]; /* saved partial block */
int num; /* used by cfb/ofb mode */
- char *app_data; /* application stuff */
+ void *app_data; /* application stuff */
+ int key_len; /* May change for variable length cipher */
union {
#ifndef NO_RC4
struct
CAST_KEY cast_ks;/* key schedule */
#endif
} c;
- } EVP_CIPHER_CTX;
+ };
typedef struct evp_Encode_Ctx_st
{
#define EVP_CIPHER_CTX_cipher(e) ((e)->cipher)
#define EVP_CIPHER_CTX_nid(e) ((e)->cipher->nid)
#define EVP_CIPHER_CTX_block_size(e) ((e)->cipher->block_size)
-#define EVP_CIPHER_CTX_key_length(e) ((e)->cipher->key_len)
+#define EVP_CIPHER_CTX_key_length(e) ((e)->key_len)
#define EVP_CIPHER_CTX_iv_length(e) ((e)->cipher->iv_len)
#define EVP_CIPHER_CTX_get_app_data(e) ((e)->app_data)
#define EVP_CIPHER_CTX_set_app_data(e,d) ((e)->app_data=(char *)(d))
void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a);
void EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a);
+int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen);
#ifdef HEADER_BIO_H
BIO_METHOD *BIO_f_md(void);
/* Function codes. */
#define EVP_F_D2I_PKEY 100
+#define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH 122
#define EVP_F_EVP_DECRYPTFINAL 101
#define EVP_F_EVP_MD_CTX_COPY 110
#define EVP_F_EVP_OPENINIT 102
#define EVP_R_EXPECTING_A_DH_KEY 128
#define EVP_R_EXPECTING_A_DSA_KEY 129
#define EVP_R_INPUT_NOT_INITIALIZED 111
+#define EVP_R_INVALID_KEY_LENGTH 130
#define EVP_R_IV_TOO_LARGE 102
#define EVP_R_KEYGEN_FAILURE 120
#define EVP_R_MISSING_PARAMETERS 103
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/evp.h>
+#include <openssl/err.h>
const char *EVP_version="EVP" OPENSSL_VERSION_PTEXT;
unsigned char *key, unsigned char *iv)
{
if (cipher != NULL)
+ {
ctx->cipher=cipher;
+ ctx->key_len = cipher->key_len;
+ }
ctx->cipher->init(ctx,key,iv,1);
ctx->encrypt=1;
ctx->buf_len=0;
unsigned char *key, unsigned char *iv)
{
if (cipher != NULL)
+ {
ctx->cipher=cipher;
+ ctx->key_len = cipher->key_len;
+ }
ctx->cipher->init(ctx,key,iv,0);
ctx->encrypt=0;
ctx->buf_len=0;
memset(c,0,sizeof(EVP_CIPHER_CTX));
}
+int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
+ {
+ if(c->key_len == keylen) return 1;
+ if((keylen > 0) && (c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH))
+ {
+ c->key_len = keylen;
+ return 1;
+ }
+ EVPerr(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH,EVP_R_INVALID_KEY_LENGTH);
+ return 0;
+ }
+
static ERR_STRING_DATA EVP_str_functs[]=
{
{ERR_PACK(0,EVP_F_D2I_PKEY,0), "D2I_PKEY"},
+{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"},
{ERR_PACK(0,EVP_F_EVP_OPENINIT,0), "EVP_OpenInit"},
{EVP_R_EXPECTING_A_DH_KEY ,"expecting a dh key"},
{EVP_R_EXPECTING_A_DSA_KEY ,"expecting a dsa key"},
{EVP_R_INPUT_NOT_INITIALIZED ,"input not initialized"},
+{EVP_R_INVALID_KEY_LENGTH ,"invalid key length"},
{EVP_R_IV_TOO_LARGE ,"iv too large"},
{EVP_R_KEYGEN_FAILURE ,"keygen failure"},
{EVP_R_MISSING_PARAMETERS ,"missing parameters"},
STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
X509_ALGOR *xalg=NULL;
PKCS7_RECIP_INFO *ri=NULL;
-#ifndef NO_RC2
- char is_rc2 = 0;
-#endif
-/* EVP_PKEY *pkey; */
-#if 0
- X509_STORE_CTX s_ctx;
-#endif
i=OBJ_obj2nid(p7->type);
p7->state=PKCS7_S_HEADER;
goto err;
}
- if(EVP_CIPHER_nid(evp_cipher) == NID_rc2_cbc)
- {
-#ifndef NO_RC2
- is_rc2 = 1;
-#else
- PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
- goto err;
-#endif
- }
-
/* We will be checking the signature */
if (md_sk != NULL)
{
return(NULL);
if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) {
- /* HACK: some S/MIME clients don't use the same key
+ /* Some S/MIME clients don't use the same key
* and effective key length. The key length is
* determined by the size of the decrypted RSA key.
- * So we hack things to manually set the RC2 key
- * because we currently can't do this with the EVP
- * interface.
*/
-#ifndef NO_RC2
- if(is_rc2) RC2_set_key(&(evp_ctx->c.rc2_ks),jj, tmp,
- EVP_CIPHER_CTX_key_length(evp_ctx)*8);
- else
-#endif
+ if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, jj))
{
PKCS7err(PKCS7_F_PKCS7_DATADECODE,
PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH);
goto err;
}
- } else EVP_CipherInit(evp_ctx,NULL,tmp,NULL,0);
+ }
+ EVP_CipherInit(evp_ctx,NULL,tmp,NULL,0);
memset(tmp,0,jj);