X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fevp%2Fe_des3.c;h=8d7b7de292bcf494e1b7adf5f01886bcbfb54dd0;hp=f9e20c8194fd35ff5f9a5e3db5fa9d7f0ff6e205;hb=d0666f289ac013094bbbf547bfbcd616199b7d2d;hpb=135883505078a868349e0a3c24514099e3cb2dac diff --git a/crypto/evp/e_des3.c b/crypto/evp/e_des3.c index f9e20c8194..8d7b7de292 100644 --- a/crypto/evp/e_des3.c +++ b/crypto/evp/e_des3.c @@ -56,12 +56,16 @@ * [including the GNU Public Licence.] */ -#ifndef OPENSSL_NO_DES #include #include "cryptlib.h" +#ifndef OPENSSL_NO_DES #include #include #include "evp_locl.h" +#include +#include + +#ifndef OPENSSL_FIPS static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv,int enc); @@ -69,29 +73,53 @@ static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv,int enc); +static int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr); + +typedef struct + { + DES_key_schedule ks1;/* key schedule */ + DES_key_schedule ks2;/* key schedule (for ede) */ + DES_key_schedule ks3;/* key schedule (for ede3) */ + } DES_EDE_KEY; + +#define data(ctx) ((DES_EDE_KEY *)(ctx)->cipher_data) + /* Because of various casts and different args can't use IMPLEMENT_BLOCK_CIPHER */ static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl) + const unsigned char *in, size_t inl) { BLOCK_CIPHER_ecb_loop() - des_ecb3_encrypt((des_cblock *)(in + i), (des_cblock *)(out + i), - ctx->c.des_ede.ks1, ctx->c.des_ede.ks2, ctx->c.des_ede.ks3, - ctx->encrypt); + DES_ecb3_encrypt((const_DES_cblock *)(in + i), + (DES_cblock *)(out + i), + &data(ctx)->ks1, &data(ctx)->ks2, + &data(ctx)->ks3, + ctx->encrypt); return 1; } static int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl) + const unsigned char *in, size_t inl) { - des_ede3_ofb64_encrypt(in, out, (long)inl, - ctx->c.des_ede.ks1, ctx->c.des_ede.ks2, ctx->c.des_ede.ks3, - (des_cblock *)ctx->iv, &ctx->num); + while (inl>=EVP_MAXCHUNK) + { + DES_ede3_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK, + &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, + (DES_cblock *)ctx->iv, &ctx->num); + inl-=EVP_MAXCHUNK; + in +=EVP_MAXCHUNK; + out+=EVP_MAXCHUNK; + } + if (inl) + DES_ede3_ofb64_encrypt(in, out, (long)inl, + &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, + (DES_cblock *)ctx->iv, &ctx->num); + return 1; } static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl) + const unsigned char *in, size_t inl) { #ifdef KSSL_DEBUG { @@ -104,58 +132,131 @@ static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, printf("\n"); } #endif /* KSSL_DEBUG */ - des_ede3_cbc_encrypt(in, out, (long)inl, - ctx->c.des_ede.ks1, ctx->c.des_ede.ks2, ctx->c.des_ede.ks3, - (des_cblock *)ctx->iv, ctx->encrypt); + while (inl>=EVP_MAXCHUNK) + { + DES_ede3_cbc_encrypt(in, out, (long)EVP_MAXCHUNK, + &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, + (DES_cblock *)ctx->iv, ctx->encrypt); + inl-=EVP_MAXCHUNK; + in +=EVP_MAXCHUNK; + out+=EVP_MAXCHUNK; + } + if (inl) + DES_ede3_cbc_encrypt(in, out, (long)inl, + &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, + (DES_cblock *)ctx->iv, ctx->encrypt); return 1; } -static int des_ede_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl) +static int des_ede_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) { - des_ede3_cfb64_encrypt(in, out, (long)inl, - ctx->c.des_ede.ks1, ctx->c.des_ede.ks2, ctx->c.des_ede.ks3, - (des_cblock *)ctx->iv, &ctx->num, ctx->encrypt); + while (inl>=EVP_MAXCHUNK) + { + DES_ede3_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK, + &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, + (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt); + inl-=EVP_MAXCHUNK; + in +=EVP_MAXCHUNK; + out+=EVP_MAXCHUNK; + } + if (inl) + DES_ede3_cfb64_encrypt(in, out, (long)inl, + &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, + (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt); return 1; } -#define NID_des_ede_ecb NID_des_ede +/* Although we have a CFB-r implementation for 3-DES, it doesn't pack the right + way, so wrap it here */ +static int des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) + { + size_t n; + unsigned char c[1],d[1]; + + for(n=0 ; n < inl ; ++n) + { + c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0; + DES_ede3_cfb_encrypt(c,d,1,1, + &data(ctx)->ks1,&data(ctx)->ks2,&data(ctx)->ks3, + (DES_cblock *)ctx->iv,ctx->encrypt); + out[n/8]=(out[n/8]&~(0x80 >> (unsigned int)(n%8))) | + ((d[0]&0x80) >> (unsigned int)(n%8)); + } + + return 1; + } + +static int des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) + { + while (inl>=EVP_MAXCHUNK) + { + DES_ede3_cfb_encrypt(in,out,8,(long)EVP_MAXCHUNK, + &data(ctx)->ks1,&data(ctx)->ks2,&data(ctx)->ks3, + (DES_cblock *)ctx->iv,ctx->encrypt); + inl-=EVP_MAXCHUNK; + in +=EVP_MAXCHUNK; + out+=EVP_MAXCHUNK; + } + if (inl) + DES_ede3_cfb_encrypt(in,out,8,(long)inl, + &data(ctx)->ks1,&data(ctx)->ks2,&data(ctx)->ks3, + (DES_cblock *)ctx->iv,ctx->encrypt); + return 1; + } -BLOCK_CIPHER_defs(des_ede, des_ede, NID_des_ede, 8, 16, 8, - 0, des_ede_init_key, NULL, +BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64, + EVP_CIPH_RAND_KEY, des_ede_init_key, NULL, EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, - NULL) + des3_ctrl) -#define NID_des_ede3_ecb NID_des_ede3 -#define des_ede3_cfb_cipher des_ede_cfb_cipher +#define des_ede3_cfb64_cipher des_ede_cfb64_cipher #define des_ede3_ofb_cipher des_ede_ofb_cipher #define des_ede3_cbc_cipher des_ede_cbc_cipher #define des_ede3_ecb_cipher des_ede_ecb_cipher -BLOCK_CIPHER_defs(des_ede3, des_ede, NID_des_ede3, 8, 24, 8, - 0, des_ede3_init_key, NULL, +BLOCK_CIPHER_defs(des_ede3, DES_EDE_KEY, NID_des_ede3, 8, 24, 8, 64, + EVP_CIPH_RAND_KEY, des_ede3_init_key, NULL, EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, - NULL) + des3_ctrl) + +BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,1, + EVP_CIPH_RAND_KEY, des_ede3_init_key,NULL, + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + des3_ctrl) + +BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,8, + EVP_CIPH_RAND_KEY, des_ede3_init_key,NULL, + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + des3_ctrl) static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { - des_cblock *deskey = (des_cblock *)key; - - 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)); + DES_cblock *deskey = (DES_cblock *)key; +#ifdef EVP_CHECK_DES_KEY + if (DES_set_key_checked(&deskey[0],&data(ctx)->ks1) + !! DES_set_key_checked(&deskey[1],&data(ctx)->ks2)) + return 0; +#else + DES_set_key_unchecked(&deskey[0],&data(ctx)->ks1); + DES_set_key_unchecked(&deskey[1],&data(ctx)->ks2); +#endif + memcpy(&data(ctx)->ks3,&data(ctx)->ks1, + sizeof(data(ctx)->ks1)); return 1; } static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { - des_cblock *deskey = (des_cblock *)key; + DES_cblock *deskey = (DES_cblock *)key; #ifdef KSSL_DEBUG { int i; @@ -167,13 +268,41 @@ static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, } #endif /* KSSL_DEBUG */ - 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); - +#ifdef EVP_CHECK_DES_KEY + if (DES_set_key_checked(&deskey[0],&data(ctx)->ks1) + || DES_set_key_checked(&deskey[1],&data(ctx)->ks2) + || DES_set_key_checked(&deskey[2],&data(ctx)->ks3)) + return 0; +#else + DES_set_key_unchecked(&deskey[0],&data(ctx)->ks1); + DES_set_key_unchecked(&deskey[1],&data(ctx)->ks2); + DES_set_key_unchecked(&deskey[2],&data(ctx)->ks3); +#endif return 1; } +static int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) + { + + DES_cblock *deskey = ptr; + + switch(type) + { + case EVP_CTRL_RAND_KEY: + if (RAND_bytes(ptr, c->key_len) <= 0) + return 0; + DES_set_odd_parity(deskey); + if (c->key_len >= 16) + DES_set_odd_parity(deskey + 1); + if (c->key_len >= 24) + DES_set_odd_parity(deskey + 2); + return 1; + + default: + return -1; + } + } + const EVP_CIPHER *EVP_des_ede(void) { return &des_ede_ecb; @@ -184,3 +313,4 @@ const EVP_CIPHER *EVP_des_ede3(void) return &des_ede3_ecb; } #endif +#endif