From 360370d9530d552078a453f7333faeab0039268f Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Sun, 28 May 2000 12:44:46 +0000 Subject: [PATCH] Third phase of EVP cipher overhaul. Remove duplicated code in EVP. --- CHANGES | 12 ++++++++- crypto/evp/e_cbc_3d.c | 25 +++++------------ crypto/evp/e_cbc_bf.c | 6 +---- crypto/evp/e_cbc_c.c | 6 +---- crypto/evp/e_cbc_d.c | 6 +---- crypto/evp/e_cbc_i.c | 19 +++++-------- crypto/evp/e_cbc_r2.c | 6 +---- crypto/evp/e_cbc_r5.c | 6 +---- crypto/evp/e_cfb_3d.c | 28 +++++-------------- crypto/evp/e_cfb_bf.c | 8 +----- crypto/evp/e_cfb_c.c | 8 +----- crypto/evp/e_cfb_d.c | 8 +----- crypto/evp/e_cfb_i.c | 8 +----- crypto/evp/e_cfb_r2.c | 8 +----- crypto/evp/e_cfb_r5.c | 8 +----- crypto/evp/e_ecb_3d.c | 18 +++++-------- crypto/evp/e_ecb_bf.c | 3 +-- crypto/evp/e_ecb_c.c | 3 +-- crypto/evp/e_ecb_d.c | 3 +-- crypto/evp/e_ecb_i.c | 17 +++++------- crypto/evp/e_ecb_r2.c | 5 ++-- crypto/evp/e_ecb_r5.c | 3 +-- crypto/evp/e_ofb_3d.c | 28 +++++-------------- crypto/evp/e_ofb_bf.c | 8 +----- crypto/evp/e_ofb_c.c | 8 +----- crypto/evp/e_ofb_d.c | 9 +------ crypto/evp/e_ofb_i.c | 8 +----- crypto/evp/e_ofb_r2.c | 8 +----- crypto/evp/e_ofb_r5.c | 8 +----- crypto/evp/e_rc4.c | 3 +-- crypto/evp/e_xcbc_d.c | 13 +++------ crypto/evp/evp.h | 16 +++++++++-- crypto/evp/evp_enc.c | 62 ++++++++++++++++++++++++++++--------------- crypto/evp/evp_err.c | 2 ++ 34 files changed, 134 insertions(+), 253 deletions(-) diff --git a/CHANGES b/CHANGES index e57e0f4fc6..c002077345 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,17 @@ Changes between 0.9.5a and 0.9.6 [xx XXX 2000] + *) 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. + + By shifting this to the top level EVP_CipherInit() it can be removed from + 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 @@ -23,7 +34,6 @@ Change lots of functions like EVP_EncryptUpdate() to now return a value: although software versions of the algorithms cannot fail any installed hardware versions can. - [Steve Henson] *) Implement SSL_OP_TLS_ROLLBACK_BUG: In ssl3_get_client_key_exchange, if diff --git a/crypto/evp/e_cbc_3d.c b/crypto/evp/e_cbc_3d.c index 7ee7851c55..bf58d4920d 100644 --- a/crypto/evp/e_cbc_3d.c +++ b/crypto/evp/e_cbc_3d.c @@ -113,18 +113,11 @@ static int des_cbc_ede_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, { des_cblock *deskey = (des_cblock *)key; - if (iv != NULL) - memcpy(&(ctx->oiv[0]),iv,8); - memcpy(&(ctx->iv[0]),&(ctx->oiv[0]),8); - - if (deskey != NULL) - { - des_set_key_unchecked(&deskey[0],ctx->c.des_ede.ks1); - des_set_key_unchecked(&deskey[1],ctx->c.des_ede.ks2); - memcpy( (char *)ctx->c.des_ede.ks3, + des_set_key_unchecked(&deskey[0],ctx->c.des_ede.ks1); + des_set_key_unchecked(&deskey[1],ctx->c.des_ede.ks2); + memcpy( (char *)ctx->c.des_ede.ks3, (char *)ctx->c.des_ede.ks1, sizeof(ctx->c.des_ede.ks1)); - } return 1; } @@ -133,16 +126,10 @@ static int des_cbc_ede3_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, { des_cblock *deskey = (des_cblock *)key; - if (iv != NULL) - memcpy(&(ctx->oiv[0]),iv,8); - memcpy(&(ctx->iv[0]),&(ctx->oiv[0]),8); + des_set_key_unchecked(&deskey[0],ctx->c.des_ede.ks1); + des_set_key_unchecked(&deskey[1],ctx->c.des_ede.ks2); + des_set_key_unchecked(&deskey[2],ctx->c.des_ede.ks3); - if (deskey != NULL) - { - des_set_key_unchecked(&deskey[0],ctx->c.des_ede.ks1); - des_set_key_unchecked(&deskey[1],ctx->c.des_ede.ks2); - des_set_key_unchecked(&deskey[2],ctx->c.des_ede.ks3); - } return 1; } diff --git a/crypto/evp/e_cbc_bf.c b/crypto/evp/e_cbc_bf.c index feda9e7e02..a2e1413266 100644 --- a/crypto/evp/e_cbc_bf.c +++ b/crypto/evp/e_cbc_bf.c @@ -89,11 +89,7 @@ EVP_CIPHER *EVP_bf_cbc(void) static int bf_cbc_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, unsigned char *iv, int enc) { - if (iv != NULL) - 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_CIPHER_CTX_key_length(ctx),key); + BF_set_key(&(ctx->c.bf_ks),EVP_CIPHER_CTX_key_length(ctx),key); return 1; } diff --git a/crypto/evp/e_cbc_c.c b/crypto/evp/e_cbc_c.c index d910f67cc5..8164f2b1cd 100644 --- a/crypto/evp/e_cbc_c.c +++ b/crypto/evp/e_cbc_c.c @@ -90,11 +90,7 @@ EVP_CIPHER *EVP_cast5_cbc(void) static int cast_cbc_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, unsigned char *iv, int enc) { - if (iv != NULL) - 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_CIPHER_CTX_key_length(ctx),key); + CAST_set_key(&(ctx->c.cast_ks),EVP_CIPHER_CTX_key_length(ctx),key); return 1; } diff --git a/crypto/evp/e_cbc_d.c b/crypto/evp/e_cbc_d.c index 817d354358..2c9287b583 100644 --- a/crypto/evp/e_cbc_d.c +++ b/crypto/evp/e_cbc_d.c @@ -91,11 +91,7 @@ static int des_cbc_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, { des_cblock *deskey = (des_cblock *)key; - if (iv != NULL) - memcpy(&(ctx->oiv[0]),iv,8); - memcpy(&(ctx->iv[0]),&(ctx->oiv[0]),8); - if (deskey != NULL) - des_set_key_unchecked(deskey,ctx->c.des_ks); + des_set_key_unchecked(deskey,ctx->c.des_ks); return 1; } diff --git a/crypto/evp/e_cbc_i.c b/crypto/evp/e_cbc_i.c index 56869b577b..c2c023a1b8 100644 --- a/crypto/evp/e_cbc_i.c +++ b/crypto/evp/e_cbc_i.c @@ -90,22 +90,15 @@ EVP_CIPHER *EVP_idea_cbc(void) static int idea_cbc_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, unsigned char *iv, int enc) { - if (iv != NULL) - memcpy(&(ctx->oiv[0]),iv,8); - memcpy(&(ctx->iv[0]),&(ctx->oiv[0]),8); - if (key != NULL) + if (enc) idea_set_encrypt_key(key,&(ctx->c.idea_ks)); + else { - if (enc) - idea_set_encrypt_key(key,&(ctx->c.idea_ks)); - else - { - IDEA_KEY_SCHEDULE tmp; + IDEA_KEY_SCHEDULE tmp; - idea_set_encrypt_key(key,&tmp); - idea_set_decrypt_key(&tmp,&(ctx->c.idea_ks)); - memset((unsigned char *)&tmp,0, + idea_set_encrypt_key(key,&tmp); + idea_set_decrypt_key(&tmp,&(ctx->c.idea_ks)); + memset((unsigned char *)&tmp,0, sizeof(IDEA_KEY_SCHEDULE)); - } } return 1; } diff --git a/crypto/evp/e_cbc_r2.c b/crypto/evp/e_cbc_r2.c index 5e91c9d21e..3552b67417 100644 --- a/crypto/evp/e_cbc_r2.c +++ b/crypto/evp/e_cbc_r2.c @@ -139,11 +139,7 @@ EVP_CIPHER *EVP_rc2_40_cbc(void) static int rc2_cbc_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, unsigned char *iv, int enc) { - if (iv != NULL) - memcpy(&(ctx->oiv[0]),iv,8); - memcpy(&(ctx->iv[0]),&(ctx->oiv[0]),8); - if (key != NULL) - RC2_set_key(&(ctx->c.rc2_ks),EVP_CIPHER_CTX_key_length(ctx), + RC2_set_key(&(ctx->c.rc2_ks),EVP_CIPHER_CTX_key_length(ctx), key,EVP_CIPHER_key_length(ctx->cipher)*8); return 1; } diff --git a/crypto/evp/e_cbc_r5.c b/crypto/evp/e_cbc_r5.c index 1639a08cdd..616644df27 100644 --- a/crypto/evp/e_cbc_r5.c +++ b/crypto/evp/e_cbc_r5.c @@ -90,11 +90,7 @@ EVP_CIPHER *EVP_rc5_32_12_16_cbc(void) static int r_32_12_16_cbc_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, unsigned char *iv, int enc) { - if (iv != NULL) - memcpy(&(ctx->oiv[0]),iv,8); - memcpy(&(ctx->iv[0]),&(ctx->oiv[0]),8); - if (key != NULL) - RC5_32_set_key(&(ctx->c.rc5_ks),EVP_RC5_32_12_16_KEY_SIZE, + RC5_32_set_key(&(ctx->c.rc5_ks),EVP_RC5_32_12_16_KEY_SIZE, key,RC5_12_ROUNDS); return 1; } diff --git a/crypto/evp/e_cfb_3d.c b/crypto/evp/e_cfb_3d.c index b07d90a036..140832703a 100644 --- a/crypto/evp/e_cfb_3d.c +++ b/crypto/evp/e_cfb_3d.c @@ -113,19 +113,11 @@ static int des_ede_cfb_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, { des_cblock *deskey = (des_cblock *)key; - ctx->num=0; - - if (iv != NULL) - memcpy(&(ctx->oiv[0]),iv,8); - memcpy(&(ctx->iv[0]),&(ctx->oiv[0]),8); - if (deskey != NULL) - { - des_set_key_unchecked(&deskey[0],ctx->c.des_ede.ks1); - des_set_key_unchecked(&deskey[1],ctx->c.des_ede.ks2); - memcpy( (char *)ctx->c.des_ede.ks3, + des_set_key_unchecked(&deskey[0],ctx->c.des_ede.ks1); + des_set_key_unchecked(&deskey[1],ctx->c.des_ede.ks2); + memcpy( (char *)ctx->c.des_ede.ks3, (char *)ctx->c.des_ede.ks1, sizeof(ctx->c.des_ede.ks1)); - } return 1; } @@ -134,17 +126,9 @@ static int des_ede3_cfb_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, { des_cblock *deskey = (des_cblock *)key; - ctx->num=0; - - if (iv != NULL) - memcpy(&(ctx->oiv[0]),iv,8); - memcpy(&(ctx->iv[0]),&(ctx->oiv[0]),8); - if (deskey != NULL) - { - des_set_key_unchecked(&deskey[0],ctx->c.des_ede.ks1); - des_set_key_unchecked(&deskey[1],ctx->c.des_ede.ks2); - des_set_key_unchecked(&deskey[2],ctx->c.des_ede.ks3); - } + des_set_key_unchecked(&deskey[0],ctx->c.des_ede.ks1); + des_set_key_unchecked(&deskey[1],ctx->c.des_ede.ks2); + des_set_key_unchecked(&deskey[2],ctx->c.des_ede.ks3); return 1; } diff --git a/crypto/evp/e_cfb_bf.c b/crypto/evp/e_cfb_bf.c index c1e7a7c935..b82139ac40 100644 --- a/crypto/evp/e_cfb_bf.c +++ b/crypto/evp/e_cfb_bf.c @@ -89,13 +89,7 @@ EVP_CIPHER *EVP_bf_cfb(void) static int bf_cfb_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, unsigned char *iv, int enc) { - ctx->num=0; - - if (iv != NULL) - 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_CIPHER_CTX_key_length(ctx),key); + BF_set_key(&(ctx->c.bf_ks),EVP_CIPHER_CTX_key_length(ctx),key); return 1; } diff --git a/crypto/evp/e_cfb_c.c b/crypto/evp/e_cfb_c.c index d29e5948a4..bbdeac24f4 100644 --- a/crypto/evp/e_cfb_c.c +++ b/crypto/evp/e_cfb_c.c @@ -90,13 +90,7 @@ EVP_CIPHER *EVP_cast5_cfb(void) static int cast_cfb_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, unsigned char *iv, int enc) { - ctx->num=0; - - if (iv != NULL) - 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_CIPHER_CTX_key_length(ctx),key); + CAST_set_key(&(ctx->c.cast_ks),EVP_CIPHER_CTX_key_length(ctx),key); return 1; } diff --git a/crypto/evp/e_cfb_d.c b/crypto/evp/e_cfb_d.c index 63d4dff681..72a26e32cf 100644 --- a/crypto/evp/e_cfb_d.c +++ b/crypto/evp/e_cfb_d.c @@ -91,13 +91,7 @@ static int des_cfb_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, { des_cblock *deskey = (des_cblock *)key; - ctx->num=0; - - if (iv != NULL) - memcpy(&(ctx->oiv[0]),iv,8); - memcpy(&(ctx->iv[0]),&(ctx->oiv[0]),8); - if (deskey != NULL) - des_set_key_unchecked(deskey,ctx->c.des_ks); + des_set_key_unchecked(deskey,ctx->c.des_ks); return 1; } diff --git a/crypto/evp/e_cfb_i.c b/crypto/evp/e_cfb_i.c index d0da6e0382..eb5b8f400d 100644 --- a/crypto/evp/e_cfb_i.c +++ b/crypto/evp/e_cfb_i.c @@ -90,13 +90,7 @@ EVP_CIPHER *EVP_idea_cfb(void) static int idea_cfb_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, unsigned char *iv, int enc) { - ctx->num=0; - - if (iv != NULL) - memcpy(&(ctx->oiv[0]),iv,8); - memcpy(&(ctx->iv[0]),&(ctx->oiv[0]),8); - if (key != NULL) - idea_set_encrypt_key(key,&(ctx->c.idea_ks)); + idea_set_encrypt_key(key,&(ctx->c.idea_ks)); return 1; } diff --git a/crypto/evp/e_cfb_r2.c b/crypto/evp/e_cfb_r2.c index 2e0fd53763..661bfad8b4 100644 --- a/crypto/evp/e_cfb_r2.c +++ b/crypto/evp/e_cfb_r2.c @@ -90,13 +90,7 @@ EVP_CIPHER *EVP_rc2_cfb(void) static int rc2_cfb_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, unsigned char *iv, int enc) { - ctx->num=0; - - if (iv != NULL) - memcpy(&(ctx->oiv[0]),iv,8); - memcpy(&(ctx->iv[0]),&(ctx->oiv[0]),8); - if (key != NULL) - RC2_set_key(&(ctx->c.rc2_ks),EVP_CIPHER_CTX_key_length(ctx), + RC2_set_key(&(ctx->c.rc2_ks),EVP_CIPHER_CTX_key_length(ctx), key,EVP_CIPHER_key_length(ctx->cipher)*8); return 1; } diff --git a/crypto/evp/e_cfb_r5.c b/crypto/evp/e_cfb_r5.c index bd092b4cd5..730fcc4fac 100644 --- a/crypto/evp/e_cfb_r5.c +++ b/crypto/evp/e_cfb_r5.c @@ -90,13 +90,7 @@ EVP_CIPHER *EVP_rc5_32_12_16_cfb(void) static int rc5_32_12_16_cfb_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, unsigned char *iv, int enc) { - ctx->num=0; - - if (iv != NULL) - memcpy(&(ctx->oiv[0]),iv,8); - memcpy(&(ctx->iv[0]),&(ctx->oiv[0]),8); - if (key != NULL) - RC5_32_set_key(&(ctx->c.rc5_ks),EVP_RC5_32_12_16_KEY_SIZE,key, + RC5_32_set_key(&(ctx->c.rc5_ks),EVP_RC5_32_12_16_KEY_SIZE,key, RC5_12_ROUNDS); return 1; } diff --git a/crypto/evp/e_ecb_3d.c b/crypto/evp/e_ecb_3d.c index 157fb9e6a8..f024b0068f 100644 --- a/crypto/evp/e_ecb_3d.c +++ b/crypto/evp/e_ecb_3d.c @@ -113,14 +113,11 @@ static int des_ede_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, { des_cblock *deskey = (des_cblock *)key; - if (deskey != NULL) - { - des_set_key_unchecked(&deskey[0],ctx->c.des_ede.ks1); - des_set_key_unchecked(&deskey[1],ctx->c.des_ede.ks2); - memcpy( (char *)ctx->c.des_ede.ks3, + des_set_key_unchecked(&deskey[0],ctx->c.des_ede.ks1); + des_set_key_unchecked(&deskey[1],ctx->c.des_ede.ks2); + memcpy( (char *)ctx->c.des_ede.ks3, (char *)ctx->c.des_ede.ks1, sizeof(ctx->c.des_ede.ks1)); - } return 1; } @@ -129,12 +126,9 @@ static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, { des_cblock *deskey = (des_cblock *)key; - if (deskey != NULL) - { - des_set_key_unchecked(&deskey[0],ctx->c.des_ede.ks1); - des_set_key_unchecked(&deskey[1],ctx->c.des_ede.ks2); - des_set_key_unchecked(&deskey[2],ctx->c.des_ede.ks3); - } + des_set_key_unchecked(&deskey[0],ctx->c.des_ede.ks1); + des_set_key_unchecked(&deskey[1],ctx->c.des_ede.ks2); + des_set_key_unchecked(&deskey[2],ctx->c.des_ede.ks3); return 1; } diff --git a/crypto/evp/e_ecb_bf.c b/crypto/evp/e_ecb_bf.c index c38e56d491..b63577900d 100644 --- a/crypto/evp/e_ecb_bf.c +++ b/crypto/evp/e_ecb_bf.c @@ -89,8 +89,7 @@ EVP_CIPHER *EVP_bf_ecb(void) static int bf_ecb_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, unsigned char *iv, int enc) { - if (key != NULL) - BF_set_key(&(ctx->c.bf_ks),EVP_CIPHER_CTX_key_length(ctx),key); + BF_set_key(&(ctx->c.bf_ks),EVP_CIPHER_CTX_key_length(ctx),key); return 1; } diff --git a/crypto/evp/e_ecb_c.c b/crypto/evp/e_ecb_c.c index 4b18dcc1b7..3d59b89eeb 100644 --- a/crypto/evp/e_ecb_c.c +++ b/crypto/evp/e_ecb_c.c @@ -90,8 +90,7 @@ EVP_CIPHER *EVP_cast5_ecb(void) static int cast_ecb_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, unsigned char *iv, int enc) { - if (key != NULL) - CAST_set_key(&(ctx->c.cast_ks),EVP_CIPHER_CTX_key_length(ctx),key); + CAST_set_key(&(ctx->c.cast_ks),EVP_CIPHER_CTX_key_length(ctx),key); return 1; } diff --git a/crypto/evp/e_ecb_d.c b/crypto/evp/e_ecb_d.c index fb15670e7a..deac93b01a 100644 --- a/crypto/evp/e_ecb_d.c +++ b/crypto/evp/e_ecb_d.c @@ -91,8 +91,7 @@ static int des_ecb_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, { des_cblock *deskey = (des_cblock *)key; - if (deskey != NULL) - des_set_key_unchecked(deskey,ctx->c.des_ks); + des_set_key_unchecked(deskey,ctx->c.des_ks); return 1; } diff --git a/crypto/evp/e_ecb_i.c b/crypto/evp/e_ecb_i.c index a9bc977a5e..ab8b64e723 100644 --- a/crypto/evp/e_ecb_i.c +++ b/crypto/evp/e_ecb_i.c @@ -90,19 +90,16 @@ EVP_CIPHER *EVP_idea_ecb(void) static int idea_ecb_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, unsigned char *iv, int enc) { - if (key != NULL) - { - if (enc) + if (enc) idea_set_encrypt_key(key,&(ctx->c.idea_ks)); - else - { - IDEA_KEY_SCHEDULE tmp; + else + { + IDEA_KEY_SCHEDULE tmp; - idea_set_encrypt_key(key,&tmp); - idea_set_decrypt_key(&tmp, &(ctx->c.idea_ks)); - memset((unsigned char *)&tmp,0, + idea_set_encrypt_key(key,&tmp); + idea_set_decrypt_key(&tmp, &(ctx->c.idea_ks)); + memset((unsigned char *)&tmp,0, sizeof(IDEA_KEY_SCHEDULE)); - } } return 1; } diff --git a/crypto/evp/e_ecb_r2.c b/crypto/evp/e_ecb_r2.c index b6ff7b77a5..596b78ba72 100644 --- a/crypto/evp/e_ecb_r2.c +++ b/crypto/evp/e_ecb_r2.c @@ -90,9 +90,8 @@ EVP_CIPHER *EVP_rc2_ecb(void) static int rc2_ecb_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, unsigned char *iv, int enc) { - if (key != NULL) - RC2_set_key(&(ctx->c.rc2_ks),EVP_CIPHER_CTX_key_length(ctx), - key,EVP_CIPHER_key_length(ctx->cipher)*8); + RC2_set_key(&(ctx->c.rc2_ks),EVP_CIPHER_CTX_key_length(ctx), + key,EVP_CIPHER_key_length(ctx->cipher)*8); return 1; } diff --git a/crypto/evp/e_ecb_r5.c b/crypto/evp/e_ecb_r5.c index ba55e41a6c..1baadb7be5 100644 --- a/crypto/evp/e_ecb_r5.c +++ b/crypto/evp/e_ecb_r5.c @@ -90,8 +90,7 @@ EVP_CIPHER *EVP_rc5_32_12_16_ecb(void) static int rc5_32_12_16_ecb_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, unsigned char *iv, int enc) { - if (key != NULL) - RC5_32_set_key(&(ctx->c.rc5_ks),EVP_RC5_32_12_16_KEY_SIZE,key, + RC5_32_set_key(&(ctx->c.rc5_ks),EVP_RC5_32_12_16_KEY_SIZE,key, RC5_12_ROUNDS); return 1; } diff --git a/crypto/evp/e_ofb_3d.c b/crypto/evp/e_ofb_3d.c index f8b3141935..14ac11c31e 100644 --- a/crypto/evp/e_ofb_3d.c +++ b/crypto/evp/e_ofb_3d.c @@ -113,19 +113,12 @@ static int des_ede_ofb_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, { des_cblock *deskey = (des_cblock *)key; - ctx->num=0; - - if (iv != NULL) - memcpy(&(ctx->oiv[0]),iv,8); - memcpy(&(ctx->iv[0]),&(ctx->oiv[0]),8); - if (deskey != NULL) - { - des_set_key_unchecked(&deskey[0],ctx->c.des_ede.ks1); - des_set_key_unchecked(&deskey[1],ctx->c.des_ede.ks2); - memcpy( (char *)ctx->c.des_ede.ks3, + des_set_key_unchecked(&deskey[0],ctx->c.des_ede.ks1); + des_set_key_unchecked(&deskey[1],ctx->c.des_ede.ks2); + memcpy( (char *)ctx->c.des_ede.ks3, (char *)ctx->c.des_ede.ks1, sizeof(ctx->c.des_ede.ks1)); - } + return 1; } @@ -134,17 +127,10 @@ static int des_ede3_ofb_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, { des_cblock *deskey = (des_cblock *)key; - ctx->num=0; + des_set_key_unchecked(&deskey[0],ctx->c.des_ede.ks1); + des_set_key_unchecked(&deskey[1],ctx->c.des_ede.ks2); + des_set_key_unchecked(&deskey[2],ctx->c.des_ede.ks3); - if (iv != NULL) - memcpy(&(ctx->oiv[0]),iv,8); - memcpy(&(ctx->iv[0]),&(ctx->oiv[0]),8); - if (deskey != NULL) - { - des_set_key_unchecked(&deskey[0],ctx->c.des_ede.ks1); - des_set_key_unchecked(&deskey[1],ctx->c.des_ede.ks2); - des_set_key_unchecked(&deskey[2],ctx->c.des_ede.ks3); - } return 1; } diff --git a/crypto/evp/e_ofb_bf.c b/crypto/evp/e_ofb_bf.c index f5507a22f7..6d4b62a391 100644 --- a/crypto/evp/e_ofb_bf.c +++ b/crypto/evp/e_ofb_bf.c @@ -89,13 +89,7 @@ EVP_CIPHER *EVP_bf_ofb(void) static int bf_ofb_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, unsigned char *iv, int enc) { - ctx->num=0; - - if (iv != NULL) - 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_CIPHER_CTX_key_length(ctx),key); + BF_set_key(&(ctx->c.bf_ks),EVP_CIPHER_CTX_key_length(ctx),key); return 1; } diff --git a/crypto/evp/e_ofb_c.c b/crypto/evp/e_ofb_c.c index b84a42d7f5..20c843c22f 100644 --- a/crypto/evp/e_ofb_c.c +++ b/crypto/evp/e_ofb_c.c @@ -90,13 +90,7 @@ EVP_CIPHER *EVP_cast5_ofb(void) static int cast_ofb_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, unsigned char *iv, int enc) { - ctx->num=0; - - if (iv != NULL) - 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_CIPHER_CTX_key_length(ctx),key); + CAST_set_key(&(ctx->c.cast_ks),EVP_CIPHER_CTX_key_length(ctx),key); return 1; } diff --git a/crypto/evp/e_ofb_d.c b/crypto/evp/e_ofb_d.c index b52ebdc016..0926e9cb7b 100644 --- a/crypto/evp/e_ofb_d.c +++ b/crypto/evp/e_ofb_d.c @@ -90,14 +90,7 @@ static int des_ofb_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, unsigned char *iv, int enc) { des_cblock *deskey = (des_cblock *)key; - - ctx->num=0; - - if (iv != NULL) - memcpy(&(ctx->oiv[0]),iv,8); - memcpy(&(ctx->iv[0]),&(ctx->oiv[0]),8); - if (deskey != NULL) - des_set_key_unchecked(deskey,ctx->c.des_ks); + des_set_key_unchecked(deskey,ctx->c.des_ks); return 1; } diff --git a/crypto/evp/e_ofb_i.c b/crypto/evp/e_ofb_i.c index 36c14b492e..b6f6aa2f53 100644 --- a/crypto/evp/e_ofb_i.c +++ b/crypto/evp/e_ofb_i.c @@ -90,13 +90,7 @@ EVP_CIPHER *EVP_idea_ofb(void) static int idea_ofb_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, unsigned char *iv, int enc) { - ctx->num=0; - - if (iv != NULL) - memcpy(&(ctx->oiv[0]),iv,8); - memcpy(&(ctx->iv[0]),&(ctx->oiv[0]),8); - if (key != NULL) - idea_set_encrypt_key(key,&(ctx->c.idea_ks)); + idea_set_encrypt_key(key,&(ctx->c.idea_ks)); return 1; } diff --git a/crypto/evp/e_ofb_r2.c b/crypto/evp/e_ofb_r2.c index bfbd602616..b71cc78bcb 100644 --- a/crypto/evp/e_ofb_r2.c +++ b/crypto/evp/e_ofb_r2.c @@ -90,13 +90,7 @@ EVP_CIPHER *EVP_rc2_ofb(void) static int rc2_ofb_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, unsigned char *iv, int enc) { - ctx->num=0; - - if (iv != NULL) - memcpy(&(ctx->oiv[0]),iv,8); - memcpy(&(ctx->iv[0]),&(ctx->oiv[0]),8); - if (key != NULL) - RC2_set_key(&(ctx->c.rc2_ks),EVP_CIPHER_CTX_key_length(ctx), + RC2_set_key(&(ctx->c.rc2_ks),EVP_CIPHER_CTX_key_length(ctx), key,EVP_CIPHER_key_length(ctx->cipher)*8); return 1; } diff --git a/crypto/evp/e_ofb_r5.c b/crypto/evp/e_ofb_r5.c index d97d8843a4..3eba2790c1 100644 --- a/crypto/evp/e_ofb_r5.c +++ b/crypto/evp/e_ofb_r5.c @@ -90,13 +90,7 @@ EVP_CIPHER *EVP_rc5_32_12_16_ofb(void) static int rc5_32_12_16_ofb_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, unsigned char *iv, int enc) { - ctx->num=0; - - if (iv != NULL) - memcpy(&(ctx->oiv[0]),iv,8); - memcpy(&(ctx->iv[0]),&(ctx->oiv[0]),8); - if (key != NULL) - RC5_32_set_key(&(ctx->c.rc5_ks),EVP_RC5_32_12_16_KEY_SIZE,key, + RC5_32_set_key(&(ctx->c.rc5_ks),EVP_RC5_32_12_16_KEY_SIZE,key, RC5_12_ROUNDS); return 1; } diff --git a/crypto/evp/e_rc4.c b/crypto/evp/e_rc4.c index bc108f4356..42839aef6b 100644 --- a/crypto/evp/e_rc4.c +++ b/crypto/evp/e_rc4.c @@ -110,8 +110,7 @@ EVP_CIPHER *EVP_rc4_40(void) static int rc4_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, unsigned char *iv, int enc) { - if (key != NULL) - memcpy(&(ctx->c.rc4.key[0]),key,EVP_CIPHER_CTX_key_length(ctx)); + memcpy(&(ctx->c.rc4.key[0]),key,EVP_CIPHER_CTX_key_length(ctx)); RC4_set_key(&(ctx->c.rc4.ks),EVP_CIPHER_CTX_key_length(ctx), ctx->c.rc4.key); return 1; diff --git a/crypto/evp/e_xcbc_d.c b/crypto/evp/e_xcbc_d.c index 067b721a0f..e5dcdebe16 100644 --- a/crypto/evp/e_xcbc_d.c +++ b/crypto/evp/e_xcbc_d.c @@ -91,15 +91,10 @@ static int desx_cbc_init_key(EVP_CIPHER_CTX *ctx, unsigned char *key, { des_cblock *deskey = (des_cblock *)key; - if (iv != NULL) - memcpy(&(ctx->oiv[0]),iv,8); - memcpy(&(ctx->iv[0]),&(ctx->oiv[0]),8); - if (deskey != NULL) - { - des_set_key_unchecked(deskey,ctx->c.desx_cbc.ks); - memcpy(&(ctx->c.desx_cbc.inw[0]),&(key[8]),8); - memcpy(&(ctx->c.desx_cbc.outw[0]),&(key[16]),8); - } + des_set_key_unchecked(deskey,ctx->c.desx_cbc.ks); + memcpy(&(ctx->c.desx_cbc.inw[0]),&(key[8]),8); + memcpy(&(ctx->c.desx_cbc.outw[0]),&(key[16]),8); + return 1; } diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h index 110e02f41b..2c41c7ef0c 100644 --- a/crypto/evp/evp.h +++ b/crypto/evp/evp.h @@ -335,19 +335,25 @@ struct evp_cipher_st 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 */ + void *app_data; /* Application data */ }; /* Values for cipher flags */ -/* Modes for block ciphers */ +/* Modes for ciphers */ +#define EVP_CIPH_STREAM_CIPHER 0x0 #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 +#define EVP_CIPH_MODE 0x7 /* Set if variable length cipher */ #define EVP_CIPH_VARIABLE_LENGTH 0x8 +/* Set if the iv handling should be done by the cipher itself */ +#define EVP_CIPH_CUSTOM_IV 0x10 +/* Set if the cipher's init() function should be called if key is NULL */ +#define EVP_CIPH_ALWAYS_CALL_INIT 0x20 typedef struct evp_cipher_info_st @@ -455,6 +461,8 @@ typedef int (EVP_PBE_KEYGEN)(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, #define EVP_CIPHER_block_size(e) ((e)->block_size) #define EVP_CIPHER_key_length(e) ((e)->key_len) #define EVP_CIPHER_iv_length(e) ((e)->iv_len) +#define EVP_CIPHER_flags(e) ((e)->flags) +#define EVP_CIPHER_mode(e) ((e)->flags) & EVP_CIPH_MODE) #define EVP_CIPHER_CTX_cipher(e) ((e)->cipher) #define EVP_CIPHER_CTX_nid(e) ((e)->cipher->nid) @@ -464,6 +472,8 @@ typedef int (EVP_PBE_KEYGEN)(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, #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)) #define EVP_CIPHER_CTX_type(c) EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c)) +#define EVP_CIPHER_CTX_flags(e) ((e)->cipher->flags) +#define EVP_CIPHER_CTX_mode(e) ((e)->cipher->flags & EVP_CIPH_MODE) #define EVP_ENCODE_LENGTH(l) (((l+2)/3*4)+(l/48+1)*2+80) #define EVP_DECODE_LENGTH(l) ((l+3)/4*3+80) @@ -709,6 +719,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_SET_KEY_LENGTH 122 #define EVP_F_EVP_DECRYPTFINAL 101 #define EVP_F_EVP_MD_CTX_COPY 110 @@ -748,6 +759,7 @@ void EVP_PBE_cleanup(void); #define EVP_R_IV_TOO_LARGE 102 #define EVP_R_KEYGEN_FAILURE 120 #define EVP_R_MISSING_PARAMETERS 103 +#define EVP_R_NO_CIPHER_SET 131 #define EVP_R_NO_DSA_PARAMETERS 116 #define EVP_R_NO_SIGN_FUNCTION_CONFIGURED 104 #define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED 105 diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c index dc1116ebbc..09f7d7ea5e 100644 --- a/crypto/evp/evp_enc.c +++ b/crypto/evp/evp_enc.c @@ -69,11 +69,47 @@ void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx) /* ctx->cipher=NULL; */ } -int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *data, +int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, unsigned char *key, unsigned char *iv, int enc) { - if (enc) return EVP_EncryptInit(ctx,data,key,iv); - else return EVP_DecryptInit(ctx,data,key,iv); + if(enc) enc = 1; + if (cipher) { + ctx->cipher=cipher; + ctx->key_len = cipher->key_len; + } else if(!ctx->cipher) { + EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_NO_CIPHER_SET); + return 0; + } + if(!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) { + switch(EVP_CIPHER_CTX_mode(ctx)) { + + case EVP_CIPH_STREAM_CIPHER: + case EVP_CIPH_ECB_MODE: + break; + + case EVP_CIPH_CFB_MODE: + case EVP_CIPH_OFB_MODE: + + ctx->num = 0; + + case EVP_CIPH_CBC_MODE: + + if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx)); + memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx)); + break; + + default: + return 0; + break; + } + } + + if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) { + if(!ctx->cipher->init(ctx,key,iv,enc)) return 0; + } + ctx->encrypt=enc; + ctx->buf_len=0; + return 1; } int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, @@ -94,29 +130,13 @@ int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, unsigned char *key, unsigned char *iv) { - if (cipher != NULL) - { - ctx->cipher=cipher; - ctx->key_len = cipher->key_len; - } - if(!ctx->cipher->init(ctx,key,iv,1)) return 0; - ctx->encrypt=1; - ctx->buf_len=0; - return 1; + return EVP_CipherInit(ctx, cipher, key, iv, 1); } int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, unsigned char *key, unsigned char *iv) { - if (cipher != NULL) - { - ctx->cipher=cipher; - ctx->key_len = cipher->key_len; - } - if(!ctx->cipher->init(ctx,key,iv,0)) return 0; - ctx->encrypt=0; - ctx->buf_len=0; - return 1; + return EVP_CipherInit(ctx, cipher, key, iv, 0); } diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c index 335466bfc2..d48d9442b2 100644 --- a/crypto/evp/evp_err.c +++ b/crypto/evp/evp_err.c @@ -67,6 +67,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_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"}, @@ -109,6 +110,7 @@ static ERR_STRING_DATA EVP_str_reasons[]= {EVP_R_IV_TOO_LARGE ,"iv too large"}, {EVP_R_KEYGEN_FAILURE ,"keygen failure"}, {EVP_R_MISSING_PARAMETERS ,"missing parameters"}, +{EVP_R_NO_CIPHER_SET ,"no cipher set"}, {EVP_R_NO_DSA_PARAMETERS ,"no dsa parameters"}, {EVP_R_NO_SIGN_FUNCTION_CONFIGURED ,"no sign function configured"}, {EVP_R_NO_VERIFY_FUNCTION_CONFIGURED ,"no verify function configured"},