From 82fa336908e31021d99f83e4526972adbf2c1624 Mon Sep 17 00:00:00 2001 From: Zhanna Tsitkov Date: Fri, 25 Sep 2009 15:12:27 +0000 Subject: [PATCH] Crypto modularity proj: Updated IOV crypto git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@22786 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/crypto/openssl/enc_provider/des.c | 237 ++++++++++++++------ src/lib/crypto/openssl/enc_provider/des3.c | 240 ++++++++++++--------- src/lib/crypto/openssl/enc_provider/rc4.c | 41 ++-- 3 files changed, 326 insertions(+), 192 deletions(-) diff --git a/src/lib/crypto/openssl/enc_provider/des.c b/src/lib/crypto/openssl/enc_provider/des.c index 3aed648fd..b7a05db7c 100644 --- a/src/lib/crypto/openssl/enc_provider/des.c +++ b/src/lib/crypto/openssl/enc_provider/des.c @@ -1,34 +1,69 @@ -/* +/* lib/crypto/openssl/enc_provider/des.c */ #include "k5-int.h" -#include "des_int.h" -#include "enc_provider.h" #include #include #include +#include "des_int.h" #define DES_BLOCK_SIZE 8 #define DES_KEY_BYTES 7 +static krb5_error_code +validate(const krb5_keyblock *key, const krb5_data *ivec, + const krb5_data *input, const krb5_data *output) +{ + /* key->enctype was checked by the caller */ + if (key->length != KRB5_MIT_DES_KEYSIZE) + return(KRB5_BAD_KEYSIZE); + if ((input->length%8) != 0) + return(KRB5_BAD_MSIZE); + if (ivec && (ivec->length != 8)) + return(KRB5_BAD_MSIZE); + if (input->length != output->length) + return(KRB5_BAD_MSIZE); + + return 0; +} + +static krb5_error_code +validate_iov(const krb5_keyblock *key, const krb5_data *ivec, + const krb5_crypto_iov *data, size_t num_data) +{ + size_t i, input_length; + + for (i = 0, input_length = 0; i < num_data; i++) { + const krb5_crypto_iov *iov = &data[i]; + + if (ENCRYPT_IOV(iov)) + input_length += iov->data.length; + } + + if (key->length != KRB5_MIT_DES3_KEYSIZE) + return(KRB5_BAD_KEYSIZE); + if ((input_length%DES_BLOCK_SIZE) != 0) + return(KRB5_BAD_MSIZE); + if (ivec && (ivec->length != 8)) + return(KRB5_BAD_MSIZE); + + return 0; +} + static krb5_error_code k5_des_encrypt(const krb5_keyblock *key, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { int ret = 0, tmp_len = 0; - EVP_CIPHER_CTX ciph_ctx; + unsigned int tmp_buf_len = 0; unsigned char *keybuf = NULL; unsigned char *tmp_buf = NULL; unsigned char iv[EVP_MAX_IV_LENGTH]; + EVP_CIPHER_CTX ciph_ctx; - if (key->length != KRB5_MIT_DES_KEYSIZE) - return(KRB5_BAD_KEYSIZE); - if ((input->length%8) != 0) - return(KRB5_BAD_MSIZE); - if (ivec && (ivec->length != 8)) - return(KRB5_BAD_MSIZE); - if (input->length != output->length) - return(KRB5_BAD_MSIZE); + ret = validate(key, ivec, input, output); + if (ret) + return ret; keybuf=key->contents; keybuf[key->length] = '\0'; @@ -38,7 +73,8 @@ k5_des_encrypt(const krb5_keyblock *key, const krb5_data *ivec, memcpy(iv,ivec->data,ivec->length); } - tmp_buf=OPENSSL_malloc(output->length); + tmp_buf_len = output->length*2; + tmp_buf=OPENSSL_malloc(tmp_buf_len); if (!tmp_buf) return ENOMEM; memset(tmp_buf,0,output->length); @@ -51,7 +87,9 @@ k5_des_encrypt(const krb5_keyblock *key, const krb5_data *ivec, EVP_CIPHER_CTX_set_padding(&ciph_ctx,0); ret = EVP_EncryptUpdate(&ciph_ctx, tmp_buf, &tmp_len, (unsigned char *)input->data, input->length); - if (ret) { + if (!ret || output->length < (unsigned int)tmp_len) { + return KRB5_CRYPTO_INTERNAL; + } else { output->length = tmp_len; ret = EVP_EncryptFinal_ex(&ciph_ctx, tmp_buf + tmp_len, &tmp_len); } @@ -62,7 +100,7 @@ k5_des_encrypt(const krb5_keyblock *key, const krb5_data *ivec, if (ret) memcpy(output->data,tmp_buf, output->length); - memset(tmp_buf,0,output->length); + memset(tmp_buf, 0, tmp_buf_len); OPENSSL_free(tmp_buf); if (!ret) @@ -70,25 +108,21 @@ k5_des_encrypt(const krb5_keyblock *key, const krb5_data *ivec, return 0; } + static krb5_error_code k5_des_decrypt(const krb5_keyblock *key, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { /* key->enctype was checked by the caller */ int ret = 0, tmp_len = 0; - EVP_CIPHER_CTX ciph_ctx; unsigned char *keybuf = NULL; unsigned char *tmp_buf; unsigned char iv[EVP_MAX_IV_LENGTH]; + EVP_CIPHER_CTX ciph_ctx; - if (key->length != KRB5_MIT_DES_KEYSIZE) - return(KRB5_BAD_KEYSIZE); - if ((input->length%8) != 0) - return(KRB5_BAD_MSIZE); - if (ivec && (ivec->length != 8)) - return(KRB5_BAD_MSIZE); - if (input->length != output->length) - return(KRB5_BAD_MSIZE); + ret = validate(key, ivec, input, output); + if (ret) + return ret; keybuf=key->contents; keybuf[key->length] = '\0'; @@ -97,7 +131,6 @@ k5_des_decrypt(const krb5_keyblock *key, const krb5_data *ivec, memset(iv,0,sizeof(iv)); memcpy(iv,ivec->data,ivec->length); } - tmp_buf=OPENSSL_malloc(output->length); if (!tmp_buf) return ENOMEM; @@ -122,7 +155,7 @@ k5_des_decrypt(const krb5_keyblock *key, const krb5_data *ivec, if (ret) memcpy(output->data,tmp_buf, output->length); - memset(tmp_buf,0,output->length ); + memset(tmp_buf,0,output->length); OPENSSL_free(tmp_buf); if (!ret) @@ -136,18 +169,38 @@ k5_des_encrypt_iov(const krb5_keyblock *key, krb5_crypto_iov *data, size_t num_data) { - int ret = 0, tmp_len = 0; - unsigned int i = 0; + int ret = 0, tmp_len = MIT_DES_BLOCK_LENGTH; EVP_CIPHER_CTX ciph_ctx; unsigned char *keybuf = NULL ; - krb5_crypto_iov *iov = NULL; - unsigned char *tmp_buf = NULL; unsigned char iv[EVP_MAX_IV_LENGTH]; - if (ivec && ivec->data){ + struct iov_block_state input_pos, output_pos; + int oblock_len = MIT_DES_BLOCK_LENGTH*num_data; + unsigned char *iblock, *oblock; + + iblock = OPENSSL_malloc(MIT_DES_BLOCK_LENGTH); + if (!iblock) + return ENOMEM; + oblock = OPENSSL_malloc(oblock_len); + if (!oblock) + return ENOMEM; + + IOV_BLOCK_STATE_INIT(&input_pos); + IOV_BLOCK_STATE_INIT(&output_pos); + + keybuf=key->contents; + keybuf[key->length] = '\0'; + + ret = validate_iov(key, ivec, data, num_data); + if (ret) + return ret; + + if (ivec && ivec->data){ memset(iv,0,sizeof(iv)); memcpy(iv,ivec->data,ivec->length); - } + } + + memset(oblock, 0, oblock_len); EVP_CIPHER_CTX_init(&ciph_ctx); @@ -156,31 +209,41 @@ k5_des_encrypt_iov(const krb5_keyblock *key, if (!ret) return KRB5_CRYPTO_INTERNAL; - for (i = 0; i < num_data; i++) { - iov = &data[i]; - if (iov->data.length <= 0) break; - tmp_len = iov->data.length; - - if (ENCRYPT_DATA_IOV(iov)) { - tmp_buf=(unsigned char *)iov->data.data; - ret = EVP_EncryptUpdate(&ciph_ctx, tmp_buf, &tmp_len, - (unsigned char *)iov->data.data, iov->data.length); - if (!ret) break; - iov->data.length = tmp_len; - } + EVP_CIPHER_CTX_set_padding(&ciph_ctx,0); + + for (;;) { + + if (!krb5int_c_iov_get_block(iblock, MIT_DES_BLOCK_LENGTH, data, num_data, &input_pos)) + break; + + if (input_pos.iov_pos == num_data) + break; + + ret = EVP_EncryptUpdate(&ciph_ctx, oblock, &tmp_len, + (unsigned char *)iblock, input_pos.data_pos); + if (!ret) break; + + krb5int_c_iov_put_block(data, num_data, oblock, MIT_DES_BLOCK_LENGTH, &output_pos); } + if(ret) - ret = EVP_EncryptFinal_ex(&ciph_ctx, (unsigned char *)tmp_buf, &tmp_len); + ret = EVP_EncryptFinal_ex(&ciph_ctx, oblock+16, &tmp_len); - if (ret) - iov->data.length += tmp_len; + if (ret) { + if (ivec != NULL) + memcpy(iv, oblock, MIT_DES_BLOCK_LENGTH); + } EVP_CIPHER_CTX_cleanup(&ciph_ctx); + memset(iblock,0,sizeof(iblock)); + memset(oblock,0,sizeof(oblock)); + OPENSSL_free(iblock); + OPENSSL_free(oblock); + if (!ret) return KRB5_CRYPTO_INTERNAL; return 0; - } static krb5_error_code @@ -189,45 +252,81 @@ k5_des_decrypt_iov(const krb5_keyblock *key, krb5_crypto_iov *data, size_t num_data) { - int ret = 0, tmp_len = 0; - unsigned int i = 0; + int ret = 0, tmp_len = MIT_DES_BLOCK_LENGTH; EVP_CIPHER_CTX ciph_ctx; unsigned char *keybuf = NULL ; - krb5_crypto_iov *iov = NULL; - unsigned char *tmp_buf = NULL; unsigned char iv[EVP_MAX_IV_LENGTH]; - if (ivec && ivec->data){ + struct iov_block_state input_pos, output_pos; + int oblock_len = MIT_DES_BLOCK_LENGTH*num_data; + unsigned char *iblock, *oblock; + + iblock = OPENSSL_malloc(MIT_DES_BLOCK_LENGTH); + if (!iblock) + return ENOMEM; + oblock = OPENSSL_malloc(oblock_len); + if (!oblock) + return ENOMEM; + + IOV_BLOCK_STATE_INIT(&input_pos); + IOV_BLOCK_STATE_INIT(&output_pos); + + keybuf=key->contents; + keybuf[key->length] = '\0'; + + ret = validate_iov(key, ivec, data, num_data); + if (ret) + return ret; + + if (ivec && ivec->data){ memset(iv,0,sizeof(iv)); memcpy(iv,ivec->data,ivec->length); - } + } + + memset(oblock, 0, oblock_len); + + EVP_CIPHER_CTX_init(&ciph_ctx); ret = EVP_DecryptInit_ex(&ciph_ctx, EVP_des_cbc(), NULL, keybuf, (ivec && ivec->data) ? iv : NULL); if (!ret) return KRB5_CRYPTO_INTERNAL; - for (i = 0; i < num_data; i++) { - iov = &data[i]; - if (iov->data.length <= 0) break; - tmp_len = iov->data.length; - - if (ENCRYPT_DATA_IOV(iov)) { - tmp_buf=(unsigned char *)iov->data.data; - ret = EVP_DecryptUpdate(&ciph_ctx, tmp_buf, &tmp_len, - (unsigned char *)iov->data.data, iov->data.length); - if (!ret) break; - iov->data.length = tmp_len; - } + EVP_CIPHER_CTX_set_padding(&ciph_ctx,0); + + for (;;) { + + if (!krb5int_c_iov_get_block(iblock, MIT_DES_BLOCK_LENGTH, + data, num_data, &input_pos)) + break; + + if (input_pos.iov_pos == num_data) + break; + + ret = EVP_DecryptUpdate(&ciph_ctx, oblock, &tmp_len, + (unsigned char *)iblock, + input_pos.data_pos); + if (!ret) break; + + krb5int_c_iov_put_block(data, num_data, oblock, + MIT_DES_BLOCK_LENGTH, &output_pos); } + if(ret) - ret = EVP_DecryptFinal_ex(&ciph_ctx, (unsigned char *)tmp_buf, &tmp_len); + ret = EVP_DecryptFinal_ex(&ciph_ctx, oblock+16, &tmp_len); - if (ret) - iov->data.length += tmp_len; + if (ret) { + if (ivec != NULL) + memcpy(iv, oblock, MIT_DES_BLOCK_LENGTH); + } EVP_CIPHER_CTX_cleanup(&ciph_ctx); + memset(iblock,0,sizeof(iblock)); + memset(oblock,0,sizeof(oblock)); + OPENSSL_free(iblock); + OPENSSL_free(oblock); + if (!ret) return KRB5_CRYPTO_INTERNAL; return 0; diff --git a/src/lib/crypto/openssl/enc_provider/des3.c b/src/lib/crypto/openssl/enc_provider/des3.c index ab3c6641b..4445af0d8 100644 --- a/src/lib/crypto/openssl/enc_provider/des3.c +++ b/src/lib/crypto/openssl/enc_provider/des3.c @@ -1,4 +1,4 @@ -/* +/* lib/crypto/openssl/enc_provider/des3.c */ #include "k5-int.h" @@ -14,8 +14,6 @@ static krb5_error_code validate(const krb5_keyblock *key, const krb5_data *ivec, const krb5_data *input, const krb5_data *output) { - mit_des3_key_schedule schedule; - /* key->enctype was checked by the caller */ if (key->length != KRB5_MIT_DES3_KEYSIZE) @@ -27,13 +25,6 @@ validate(const krb5_keyblock *key, const krb5_data *ivec, if (input->length != output->length) return(KRB5_BAD_MSIZE); - switch (mit_des3_key_sched(*(mit_des3_cblock *)key->contents, - schedule)) { - case -1: - return(KRB5DES_BAD_KEYPAR); - case -2: - return(KRB5DES_WEAK_KEY); - } return 0; } @@ -42,7 +33,6 @@ validate_iov(const krb5_keyblock *key, const krb5_data *ivec, const krb5_crypto_iov *data, size_t num_data) { size_t i, input_length; - mit_des3_key_schedule schedule; for (i = 0, input_length = 0; i < num_data; i++) { const krb5_crypto_iov *iov = &data[i]; @@ -58,13 +48,6 @@ validate_iov(const krb5_keyblock *key, const krb5_data *ivec, if (ivec && (ivec->length != 8)) return(KRB5_BAD_MSIZE); - switch (mit_des3_key_sched(*(mit_des3_cblock *)key->contents, - schedule)) { - case -1: - return(KRB5DES_BAD_KEYPAR); - case -2: - return(KRB5DES_WEAK_KEY); - } return 0; } @@ -72,12 +55,12 @@ static krb5_error_code k5_des3_encrypt(const krb5_keyblock *key, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { - int ret = 0, tmp_len = 0; - EVP_CIPHER_CTX ciph_ctx; + unsigned int tmp_buf_len = 0; unsigned char *keybuf = NULL; unsigned char *tmp_buf = NULL; unsigned char iv[EVP_MAX_IV_LENGTH]; + EVP_CIPHER_CTX ciph_ctx; ret = validate(key, ivec, input, output); if (ret) @@ -87,11 +70,10 @@ k5_des3_encrypt(const krb5_keyblock *key, const krb5_data *ivec, keybuf[key->length] = '\0'; if (ivec && ivec->data) { - memset(iv,0,sizeof(iv)); memcpy(iv,ivec->data,ivec->length); } - - tmp_buf = OPENSSL_malloc(output->length); + tmp_buf_len = output->length * 2; + tmp_buf = OPENSSL_malloc(tmp_buf_len); if (!tmp_buf) return ENOMEM; @@ -101,9 +83,11 @@ k5_des3_encrypt(const krb5_keyblock *key, const krb5_data *ivec, (ivec && ivec->data) ? iv : NULL); if (ret) { EVP_CIPHER_CTX_set_padding(&ciph_ctx,0); - ret = EVP_EncryptUpdate(&ciph_ctx, tmp_buf, &tmp_len, + ret = EVP_EncryptUpdate(&ciph_ctx, tmp_buf, &tmp_len, (unsigned char *)input->data, input->length); - if (ret) { + if (!ret || output->length < (unsigned int)tmp_len) { + ret = KRB5_CRYPTO_INTERNAL; + } else { output->length = tmp_len; ret = EVP_EncryptFinal_ex(&ciph_ctx, tmp_buf+tmp_len, &tmp_len); } @@ -113,11 +97,12 @@ k5_des3_encrypt(const krb5_keyblock *key, const krb5_data *ivec, if (ret) memcpy(output->data,tmp_buf, output->length); - memset(tmp_buf,0,output->length); + memset(tmp_buf, 0, tmp_buf_len); OPENSSL_free(tmp_buf); if (!ret) return KRB5_CRYPTO_INTERNAL; + return 0; } @@ -176,61 +161,44 @@ k5_des3_decrypt(const krb5_keyblock *key, const krb5_data *ivec, } -static krb5_error_code -validate_and_schedule_iov(const krb5_keyblock *key, const krb5_data *ivec, - const krb5_crypto_iov *data, size_t num_data, - mit_des3_key_schedule *schedule) -{ - size_t i, input_length; - - for (i = 0, input_length = 0; i < num_data; i++) { - const krb5_crypto_iov *iov = &data[i]; - - if (ENCRYPT_IOV(iov)) - input_length += iov->data.length; - } - - if (key->length != 24) - return(KRB5_BAD_KEYSIZE); - if ((input_length%8) != 0) - return(KRB5_BAD_MSIZE); - if (ivec && (ivec->length != 8)) - return(KRB5_BAD_MSIZE); - - switch (mit_des3_key_sched(*(mit_des3_cblock *)key->contents, - *schedule)) { - case -1: - return(KRB5DES_BAD_KEYPAR); - case -2: - return(KRB5DES_WEAK_KEY); - } - return 0; -} - static krb5_error_code k5_des3_encrypt_iov(const krb5_keyblock *key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { -#if 0 - int ret = 0, tmp_len = 0; - unsigned int i = 0; + int ret = 0, tmp_len = MIT_DES_BLOCK_LENGTH; EVP_CIPHER_CTX ciph_ctx; unsigned char *keybuf = NULL ; - krb5_crypto_iov *iov = NULL; - unsigned char *tmp_buf = NULL; unsigned char iv[EVP_MAX_IV_LENGTH]; + struct iov_block_state input_pos, output_pos; + int oblock_len = MIT_DES_BLOCK_LENGTH*num_data; + unsigned char *iblock, *oblock; + ret = validate_iov(key, ivec, data, num_data); if (ret) - return ret; + return ret; + + iblock = OPENSSL_malloc(MIT_DES_BLOCK_LENGTH); + if (!iblock) + return ENOMEM; + oblock = OPENSSL_malloc(oblock_len); + if (!oblock) + return ENOMEM; + + IOV_BLOCK_STATE_INIT(&input_pos); + IOV_BLOCK_STATE_INIT(&output_pos); + + keybuf=key->contents; + keybuf[key->length] = '\0'; if (ivec && ivec->data){ memset(iv,0,sizeof(iv)); memcpy(iv,ivec->data,ivec->length); } + memset(oblock, 0, oblock_len); EVP_CIPHER_CTX_init(&ciph_ctx); @@ -239,48 +207,43 @@ k5_des3_encrypt_iov(const krb5_keyblock *key, if (!ret) return KRB5_CRYPTO_INTERNAL; - for (i = 0; i < num_data; i++) { - iov = &data[i]; - if (iov->data.length <= 0) break; - tmp_len = iov->data.length; - - if (ENCRYPT_IOV(iov)) { - tmp_buf=(unsigned char *)iov->data.data; - ret = EVP_EncryptUpdate(&ciph_ctx, tmp_buf, &tmp_len, - (unsigned char *)iov->data.data, iov->data.length); - if (!ret) break; - iov->data.length = tmp_len; - } + EVP_CIPHER_CTX_set_padding(&ciph_ctx,0); + + for (;;) { + + if (!krb5int_c_iov_get_block(iblock, MIT_DES_BLOCK_LENGTH, + data, num_data, &input_pos)) + break; + + if (input_pos.iov_pos == num_data) + break; + + ret = EVP_EncryptUpdate(&ciph_ctx, oblock, &tmp_len, + (unsigned char *)iblock, input_pos.data_pos); + if (!ret) break; + + krb5int_c_iov_put_block(data, num_data, + oblock, MIT_DES_BLOCK_LENGTH, &output_pos); } + if(ret) - ret = EVP_EncryptFinal_ex(&ciph_ctx, (unsigned char *)tmp_buf, &tmp_len); + ret = EVP_EncryptFinal_ex(&ciph_ctx, oblock+input_pos.data_pos, &tmp_len); - if (ret) - iov->data.length += tmp_len; + if (ret) { + if (ivec != NULL) + memcpy(iv, oblock, MIT_DES_BLOCK_LENGTH); + } EVP_CIPHER_CTX_cleanup(&ciph_ctx); + memset(iblock,0,sizeof(iblock)); + memset(oblock,0,sizeof(oblock)); + OPENSSL_free(iblock); + OPENSSL_free(oblock); + if (!ret) return KRB5_CRYPTO_INTERNAL; return 0; -#endif - -//#if 0 - mit_des3_key_schedule schedule; - krb5_error_code err; - - err = validate_and_schedule_iov(key, ivec, data, num_data, &schedule); - if (err) - return err; - - /* this has a return value, but the code always returns zero */ - krb5int_des3_cbc_encrypt_iov(data, num_data, - schedule[0], schedule[1], schedule[2], - ivec != NULL ? (unsigned char *) ivec->data : NULL); - - zap(schedule, sizeof(schedule)); - return(0); -//#endif } static krb5_error_code @@ -289,21 +252,84 @@ k5_des3_decrypt_iov(const krb5_keyblock *key, krb5_crypto_iov *data, size_t num_data) { - mit_des3_key_schedule schedule; - krb5_error_code err; + int ret = 0, tmp_len = MIT_DES_BLOCK_LENGTH; + EVP_CIPHER_CTX ciph_ctx; + unsigned char *keybuf = NULL ; + unsigned char iv[EVP_MAX_IV_LENGTH]; + + struct iov_block_state input_pos, output_pos; + int oblock_len = MIT_DES_BLOCK_LENGTH*num_data; + unsigned char *iblock, *oblock; - err = validate_and_schedule_iov(key, ivec, data, num_data, &schedule); - if (err) - return err; + ret = validate_iov(key, ivec, data, num_data); + if (ret) + return ret; - /* this has a return value, but the code always returns zero */ - krb5int_des3_cbc_decrypt_iov(data, num_data, - schedule[0], schedule[1], schedule[2], - ivec != NULL ? (unsigned char *) ivec->data : NULL); + iblock = OPENSSL_malloc(MIT_DES_BLOCK_LENGTH); + if (!iblock) + return ENOMEM; + oblock = OPENSSL_malloc(oblock_len); + if (!oblock) + return ENOMEM; - zap(schedule, sizeof(schedule)); + IOV_BLOCK_STATE_INIT(&input_pos); + IOV_BLOCK_STATE_INIT(&output_pos); + + keybuf=key->contents; + keybuf[key->length] = '\0'; + + if (ivec && ivec->data){ + memset(iv,0,sizeof(iv)); + memcpy(iv,ivec->data,ivec->length); + } + + memset(oblock, 0, oblock_len); + + EVP_CIPHER_CTX_init(&ciph_ctx); - return(0); + ret = EVP_DecryptInit_ex(&ciph_ctx, EVP_des_ede3_cbc(), NULL, + keybuf, (ivec && ivec->data) ? iv : NULL); + if (!ret) + return KRB5_CRYPTO_INTERNAL; + + EVP_CIPHER_CTX_set_padding(&ciph_ctx,0); + + for (;;) { + + if (!krb5int_c_iov_get_block(iblock, MIT_DES_BLOCK_LENGTH, + data, num_data, &input_pos)) + break; + + if (input_pos.iov_pos == num_data) + break; + + ret = EVP_DecryptUpdate(&ciph_ctx, oblock, &tmp_len, + (unsigned char *)iblock, input_pos.data_pos); + if (!ret) break; + + krb5int_c_iov_put_block(data, num_data, + oblock, MIT_DES_BLOCK_LENGTH, &output_pos); + } + + if(ret) + ret = EVP_DecryptFinal_ex(&ciph_ctx, + oblock + input_pos.data_pos, &tmp_len); + + if (ret) { + if (ivec != NULL) + memcpy(iv, oblock, MIT_DES_BLOCK_LENGTH); + } + + EVP_CIPHER_CTX_cleanup(&ciph_ctx); + + memset(iblock,0,sizeof(iblock)); + memset(oblock,0,sizeof(oblock)); + OPENSSL_free(iblock); + OPENSSL_free(oblock); + + if (!ret) + return KRB5_CRYPTO_INTERNAL; + return 0; } const struct krb5_enc_provider krb5int_enc_des3 = { diff --git a/src/lib/crypto/openssl/enc_provider/rc4.c b/src/lib/crypto/openssl/enc_provider/rc4.c index 08bd859bd..455a47faa 100644 --- a/src/lib/crypto/openssl/enc_provider/rc4.c +++ b/src/lib/crypto/openssl/enc_provider/rc4.c @@ -1,11 +1,9 @@ -/* arcfour.c +/* lib/crypto/openssl/enc_provider/rc4.c * * #include STD_DISCLAIMER */ #include "k5-int.h" -#include "arcfour-int.h" -#include "enc_provider.h" #include #include #include @@ -14,17 +12,22 @@ #define RC4_BLOCK_SIZE 1 /* Interface layer to kerb5 crypto layer */ + +/* prototypes */ static krb5_error_code k5_arcfour_docrypt(const krb5_keyblock *, const krb5_data *, const krb5_data *, krb5_data *); - static krb5_error_code k5_arcfour_free_state ( krb5_data *state); static krb5_error_code k5_arcfour_init_state (const krb5_keyblock *key, krb5_keyusage keyusage, krb5_data *new_state); -/* The workhorse of the arcfour system, this impliments the cipher */ +/* The workhorse of the arcfour system, + * this impliments the cipher + */ + +/* In-place rc4 crypto */ static krb5_error_code k5_arcfour_docrypt(const krb5_keyblock *key, const krb5_data *state, const krb5_data *input, krb5_data *output) @@ -44,26 +47,30 @@ k5_arcfour_docrypt(const krb5_keyblock *key, const krb5_data *state, keybuf[key->length] = '\0'; EVP_CIPHER_CTX_init(&ciph_ctx); + ret = EVP_EncryptInit_ex(&ciph_ctx, EVP_rc4(), NULL, keybuf, NULL); if (ret) { tmp_buf=(unsigned char *)output->data; - ret = EVP_EncryptUpdate(&ciph_ctx, tmp_buf, &tmp_len, (unsigned char *)input->data, input->length); + ret = EVP_EncryptUpdate(&ciph_ctx, tmp_buf, &tmp_len, + (unsigned char *)input->data, input->length); output->length = tmp_len; } if (ret) { tmp_buf += tmp_len; ret = EVP_EncryptFinal_ex(&ciph_ctx, tmp_buf, &tmp_len); } + EVP_CIPHER_CTX_cleanup(&ciph_ctx); - output->length += tmp_len; if (!ret) return KRB5_CRYPTO_INTERNAL; + + output->length += tmp_len; + return 0; } - -/* In-place decryption */ +/* In-place IOV crypto */ static krb5_error_code k5_arcfour_docrypt_iov(const krb5_keyblock *key, const krb5_data *state, @@ -72,10 +79,10 @@ k5_arcfour_docrypt_iov(const krb5_keyblock *key, { size_t i; int ret = 0, tmp_len = 0; - EVP_CIPHER_CTX ciph_ctx; - unsigned char *keybuf = NULL ; - krb5_crypto_iov *iov = NULL; + unsigned char *keybuf = NULL ; unsigned char *tmp_buf = NULL; + krb5_crypto_iov *iov = NULL; + EVP_CIPHER_CTX ciph_ctx; keybuf=key->contents; keybuf[key->length] = '\0'; @@ -93,7 +100,7 @@ k5_arcfour_docrypt_iov(const krb5_keyblock *key, if (ENCRYPT_IOV(iov)) { tmp_buf=(unsigned char *)iov->data.data; - ret = EVP_EncryptUpdate(&ciph_ctx, + ret = EVP_EncryptUpdate(&ciph_ctx, tmp_buf, &tmp_len, (unsigned char *)iov->data.data, iov->data.length); if (!ret) break; @@ -102,12 +109,14 @@ k5_arcfour_docrypt_iov(const krb5_keyblock *key, } if(ret) ret = EVP_EncryptFinal_ex(&ciph_ctx, (unsigned char *)tmp_buf, &tmp_len); - if (ret) - iov->data.length += tmp_len; + EVP_CIPHER_CTX_cleanup(&ciph_ctx); if (!ret) - return -1; + return KRB5_CRYPTO_INTERNAL; + + iov->data.length += tmp_len; + return 0; } -- 2.26.2