aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhanna Tsitkov <tsitkova@mit.edu>2009-09-25 15:12:27 +0000
committerZhanna Tsitkov <tsitkova@mit.edu>2009-09-25 15:12:27 +0000
commit82fa336908e31021d99f83e4526972adbf2c1624 (patch)
treed420dcae0df5e388402930d8f942fcf1add04399
parent324ba91fc437b8e40ff82e710a724963051f8b5f (diff)
downloadkrb5-82fa336908e31021d99f83e4526972adbf2c1624.zip
krb5-82fa336908e31021d99f83e4526972adbf2c1624.tar.gz
krb5-82fa336908e31021d99f83e4526972adbf2c1624.tar.bz2
Crypto modularity proj: Updated IOV crypto
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@22786 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r--src/lib/crypto/openssl/enc_provider/des.c237
-rw-r--r--src/lib/crypto/openssl/enc_provider/des3.c240
-rw-r--r--src/lib/crypto/openssl/enc_provider/rc4.c41
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 3aed648..b7a05db 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 <aead.h>
#include <rand2key.h>
#include <openssl/evp.h>
+#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 ab3c664..4445af0 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;
}
@@ -177,60 +162,43 @@ 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 08bd859..455a47f 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 <aead.h>
#include <rand2key.h>
#include <openssl/evp.h>
@@ -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;
}