aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Hartman <hartmans@mit.edu>2008-12-01 16:42:18 +0000
committerSam Hartman <hartmans@mit.edu>2008-12-01 16:42:18 +0000
commit74844f649c7c77c2b96bc9ab8a1b22707138d58d (patch)
treeae2e0f1c2ab078d1d29d4480e4699d345c7193a0
parent5ff2db3b6cfa52dc5f8776d0c2a7aaebee18ef68 (diff)
downloadkrb5-74844f649c7c77c2b96bc9ab8a1b22707138d58d.zip
krb5-74844f649c7c77c2b96bc9ab8a1b22707138d58d.tar.gz
krb5-74844f649c7c77c2b96bc9ab8a1b22707138d58d.tar.bz2
Don't require KRB5_CRYPTO_TPYE_HEADER to come before data
git-svn-id: svn://anonsvn.mit.edu/krb5/branches/mskrb-integ-crypto-iov@21222 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r--src/lib/crypto/aead.h7
-rw-r--r--src/lib/crypto/des/d3_aead.c97
-rw-r--r--src/lib/crypto/dk/dk_aead.c6
-rw-r--r--src/lib/crypto/enc_provider/aes.c122
4 files changed, 140 insertions, 92 deletions
diff --git a/src/lib/crypto/aead.h b/src/lib/crypto/aead.h
index f9bfb59..ff81f47 100644
--- a/src/lib/crypto/aead.h
+++ b/src/lib/crypto/aead.h
@@ -41,10 +41,13 @@ krb5int_c_make_checksum_iov(const struct krb5_cksumtypes *cksum,
size_t num_data,
krb5_data *cksum_data);
-#define ENCRYPT_IOV(_iov) ((_iov)->flags == KRB5_CRYPTO_TYPE_HEADER || \
- (_iov)->flags == KRB5_CRYPTO_TYPE_DATA || \
+#define ENCRYPT_CONF_IOV(_iov) ((_iov)->flags == KRB5_CRYPTO_TYPE_HEADER)
+
+#define ENCRYPT_DATA_IOV(_iov) ((_iov)->flags == KRB5_CRYPTO_TYPE_DATA || \
(_iov)->flags == KRB5_CRYPTO_TYPE_PADDING)
+#define ENCRYPT_IOV(_iov) (ENCRYPT_CONF_IOV(_iov) || ENCRYPT_DATA_IOV(_iov))
+
#define SIGN_IOV(_iov) ((_iov)->flags == KRB5_CRYPTO_TYPE_HEADER || \
(_iov)->flags == KRB5_CRYPTO_TYPE_DATA || \
(_iov)->flags == KRB5_CRYPTO_TYPE_SIGN_ONLY)
diff --git a/src/lib/crypto/des/d3_aead.c b/src/lib/crypto/des/d3_aead.c
index e218bbf..b0497fe 100644
--- a/src/lib/crypto/des/d3_aead.c
+++ b/src/lib/crypto/des/d3_aead.c
@@ -25,29 +25,38 @@
#include "f_tables.h"
#include "../aead.h"
+struct iov_block_state {
+ size_t iov_pos;
+ size_t data_pos;
+ krb5_boolean got_header;
+};
+
+#define IOV_BLOCK_STATE_INIT(_state) ((_state)->iov_pos = (_state)->data_pos = (_state)->got_header = 0)
+
static void
iov_get_block(unsigned char block[MIT_DES_BLOCK_LENGTH],
const krb5_crypto_iov *data,
size_t num_data,
- size_t *x,
- size_t *y)
+ struct iov_block_state *iov_state)
{
size_t i, j = 0;
- for (i = *x; i < num_data; i++) {
+ for (i = iov_state->iov_pos; i < num_data; i++) {
const krb5_crypto_iov *iov = &data[i];
size_t nbytes;
- if (!ENCRYPT_IOV(iov))
+ if (iov_state->got_header ?
+ !ENCRYPT_DATA_IOV(iov) :
+ !ENCRYPT_CONF_IOV(iov))
continue;
- nbytes = iov->data.length - *y;
+ nbytes = iov->data.length - iov_state->data_pos;
if (nbytes > MIT_DES_BLOCK_LENGTH - j)
nbytes = MIT_DES_BLOCK_LENGTH - j;
- memcpy(block + j, iov->data.data + *y, nbytes);
+ memcpy(block + j, iov->data.data + iov_state->data_pos, nbytes);
- *y += nbytes;
+ iov_state->data_pos += nbytes;
j += nbytes;
assert(j <= MIT_DES_BLOCK_LENGTH);
@@ -55,40 +64,49 @@ iov_get_block(unsigned char block[MIT_DES_BLOCK_LENGTH],
if (j == MIT_DES_BLOCK_LENGTH)
break;
- assert(*y == iov->data.length);
+ assert(iov_state->data_pos == iov->data.length);
- *y = 0;
+ iov_state->data_pos = 0;
+ }
+
+ if (iov_state->got_header == 0 &&
+ data[i].data.length == iov_state->data_pos) {
+ /* Once we have consumed the header, return to start */
+ iov_state->iov_pos = 0;
+ iov_state->data_pos = 0;
+ iov_state->got_header = 1;
}
if (j != MIT_DES_BLOCK_LENGTH)
memset(block + j, 0, MIT_DES_BLOCK_LENGTH - j);
- *x = i;
+ iov_state->iov_pos = i;
}
static void
iov_put_block(const krb5_crypto_iov *data,
size_t num_data,
unsigned char block[MIT_DES_BLOCK_LENGTH],
- size_t *x,
- size_t *y)
+ struct iov_block_state *iov_state)
{
size_t i, j = 0;
- for (i = *x; i < num_data; i++) {
+ for (i = iov_state->iov_pos; i < num_data; i++) {
const krb5_crypto_iov *iov = &data[i];
size_t nbytes;
- if (!ENCRYPT_IOV(iov))
+ if (iov_state->got_header ?
+ !ENCRYPT_DATA_IOV(iov) :
+ !ENCRYPT_CONF_IOV(iov))
continue;
- nbytes = iov->data.length - *y;
+ nbytes = iov->data.length - iov_state->data_pos;
if (nbytes > MIT_DES_BLOCK_LENGTH - j)
nbytes = MIT_DES_BLOCK_LENGTH - j;
- memcpy(iov->data.data + *y, block + j, nbytes);
+ memcpy(iov->data.data + iov_state->data_pos, block + j, nbytes);
- *y += nbytes;
+ iov_state->data_pos += nbytes;
j += nbytes;
assert(j <= MIT_DES_BLOCK_LENGTH);
@@ -96,14 +114,21 @@ iov_put_block(const krb5_crypto_iov *data,
if (j == MIT_DES_BLOCK_LENGTH)
break;
- assert(*y == iov->data.length);
+ assert(iov_state->data_pos == iov->data.length);
- *y = 0;
+ iov_state->data_pos = 0;
}
- *x = i;
-}
+ if (iov_state->got_header == 0 &&
+ data[i].data.length == iov_state->data_pos) {
+ /* Once we have consumed the header, return to start */
+ iov_state->iov_pos = 0;
+ iov_state->data_pos = 0;
+ iov_state->got_header = 1;
+ }
+ iov_state->iov_pos = i;
+}
void
krb5int_des3_cbc_encrypt_iov(krb5_crypto_iov *data,
unsigned long num_data,
@@ -116,8 +141,10 @@ krb5int_des3_cbc_encrypt_iov(krb5_crypto_iov *data,
const unsigned DES_INT32 *kp1, *kp2, *kp3;
const unsigned char *ip;
unsigned char *op;
- size_t input_iov_pos = 0, input_block_pos = 0;
- size_t output_iov_pos = 0, output_block_pos = 0;
+ struct iov_block_state input_pos, output_pos;
+
+ IOV_BLOCK_STATE_INIT(&input_pos);
+ IOV_BLOCK_STATE_INIT(&output_pos);
/*
* Get key pointer here. This won't need to be reinitialized
@@ -146,7 +173,7 @@ krb5int_des3_cbc_encrypt_iov(krb5_crypto_iov *data,
ip = iblock;
op = oblock;
- iov_get_block(iblock, data, num_data, &input_iov_pos, &input_block_pos);
+ iov_get_block(iblock, data, num_data, &input_pos);
GET_HALF_BLOCK(temp, ip);
left ^= temp;
@@ -166,11 +193,11 @@ krb5int_des3_cbc_encrypt_iov(krb5_crypto_iov *data,
PUT_HALF_BLOCK(left, op);
PUT_HALF_BLOCK(right, op);
- iov_put_block(data, num_data, oblock, &output_iov_pos, &output_block_pos);
+ iov_put_block(data, num_data, oblock, &output_pos);
- if (input_iov_pos == num_data && ivec != NULL)
+ if (input_pos.iov_pos == num_data && ivec != NULL)
memcpy(ivec, oblock, MIT_DES_BLOCK_LENGTH);
- } while (input_iov_pos != num_data);
+ } while (input_pos.iov_pos != num_data);
}
void
@@ -184,11 +211,13 @@ krb5int_des3_cbc_decrypt_iov(krb5_crypto_iov *data,
unsigned DES_INT32 left, right;
const unsigned DES_INT32 *kp1, *kp2, *kp3;
const unsigned char *ip;
- size_t output_iov_pos = 0, output_block_pos = 0;
unsigned DES_INT32 ocipherl, ocipherr;
unsigned DES_INT32 cipherl, cipherr;
unsigned char *op;
- size_t input_iov_pos = 0, input_block_pos = 0;
+ struct iov_block_state input_pos, output_pos;
+
+ IOV_BLOCK_STATE_INIT(&input_pos);
+ IOV_BLOCK_STATE_INIT(&output_pos);
/*
* Get key pointer here. This won't need to be reinitialized
@@ -224,7 +253,7 @@ krb5int_des3_cbc_decrypt_iov(krb5_crypto_iov *data,
unsigned char iblock[MIT_DES_BLOCK_LENGTH];
unsigned char oblock[MIT_DES_BLOCK_LENGTH];
- iov_get_block(iblock, data, num_data, &input_iov_pos, &input_block_pos);
+ iov_get_block(iblock, data, num_data, &input_pos);
ip = iblock;
op = oblock;
@@ -257,9 +286,9 @@ krb5int_des3_cbc_decrypt_iov(krb5_crypto_iov *data,
ocipherl = cipherl;
ocipherr = cipherr;
- iov_put_block(data, num_data, oblock, &output_iov_pos, &output_block_pos);
+ iov_put_block(data, num_data, oblock, &output_pos);
- if (input_iov_pos == num_data && ivec != NULL)
- memcpy(ivec, iblock, MIT_DES_BLOCK_LENGTH);
- } while (input_iov_pos != num_data);
+ if (input_pos.iov_pos == num_data && ivec != NULL)
+ memcpy(ivec, oblock, MIT_DES_BLOCK_LENGTH);
+ } while (input_pos.iov_pos != num_data);
}
diff --git a/src/lib/crypto/dk/dk_aead.c b/src/lib/crypto/dk/dk_aead.c
index b319570..746b8c7 100644
--- a/src/lib/crypto/dk/dk_aead.c
+++ b/src/lib/crypto/dk/dk_aead.c
@@ -94,8 +94,7 @@ krb5int_dk_encrypt_iov(const struct krb5_aead_provider *aead,
for (i = 0; i < num_data; i++) {
const krb5_crypto_iov *iov = &data[i];
- if (iov->flags == KRB5_CRYPTO_TYPE_DATA ||
- iov->flags == KRB5_CRYPTO_TYPE_PADDING)
+ if (ENCRYPT_DATA_IOV(iov))
plainlen += iov->data.length;
}
@@ -241,8 +240,7 @@ krb5int_dk_decrypt_iov(const struct krb5_aead_provider *aead,
for (i = 0; i < num_data; i++) {
const krb5_crypto_iov *iov = &data[i];
- if (iov->flags == KRB5_CRYPTO_TYPE_DATA ||
- iov->flags == KRB5_CRYPTO_TYPE_PADDING)
+ if (ENCRYPT_DATA_IOV(iov))
cipherlen += iov->data.length;
}
diff --git a/src/lib/crypto/enc_provider/aes.c b/src/lib/crypto/enc_provider/aes.c
index 488e839..30f7063 100644
--- a/src/lib/crypto/enc_provider/aes.c
+++ b/src/lib/crypto/enc_provider/aes.c
@@ -198,29 +198,38 @@ krb5int_aes_decrypt(const krb5_keyblock *key, const krb5_data *ivec,
return 0;
}
+struct iov_block_state {
+ size_t iov_pos;
+ size_t data_pos;
+ krb5_boolean got_header;
+};
+
+#define IOV_BLOCK_STATE_INIT(_state) ((_state)->iov_pos = (_state)->data_pos = (_state)->got_header = 0)
+
static void
iov_get_block(char block[BLOCK_SIZE],
const krb5_crypto_iov *data,
size_t num_data,
- size_t *x,
- size_t *y)
+ struct iov_block_state *iov_state)
{
size_t i, j = 0;
- for (i = *x; i < num_data; i++) {
+ for (i = iov_state->iov_pos; i < num_data; i++) {
const krb5_crypto_iov *iov = &data[i];
size_t nbytes;
- if (!ENCRYPT_IOV(iov))
+ if (iov_state->got_header ?
+ !ENCRYPT_DATA_IOV(iov) :
+ !ENCRYPT_CONF_IOV(iov))
continue;
- nbytes = iov->data.length - *y;
+ nbytes = iov->data.length - iov_state->data_pos;
if (nbytes > BLOCK_SIZE - j)
nbytes = BLOCK_SIZE - j;
- memcpy(block + j, iov->data.data + *y, nbytes);
+ memcpy(block + j, iov->data.data + iov_state->data_pos, nbytes);
- *y += nbytes;
+ iov_state->data_pos += nbytes;
j += nbytes;
assert(j <= BLOCK_SIZE);
@@ -228,40 +237,49 @@ iov_get_block(char block[BLOCK_SIZE],
if (j == BLOCK_SIZE)
break;
- assert(*y == iov->data.length);
+ assert(iov_state->data_pos == iov->data.length);
- *y = 0;
+ iov_state->data_pos = 0;
+ }
+
+ if (iov_state->got_header == 0 &&
+ data[i].data.length == iov_state->data_pos) {
+ /* Once we have consumed the header, return to start */
+ iov_state->iov_pos = 0;
+ iov_state->data_pos = 0;
+ iov_state->got_header = 1;
}
if (j != BLOCK_SIZE)
memset(block + j, 0, BLOCK_SIZE - j);
- *x = i;
+ iov_state->iov_pos = i;
}
static void
iov_put_block(const krb5_crypto_iov *data,
size_t num_data,
char block[BLOCK_SIZE],
- size_t *x,
- size_t *y)
+ struct iov_block_state *iov_state)
{
size_t i, j = 0;
- for (i = *x; i < num_data; i++) {
+ for (i = iov_state->iov_pos; i < num_data; i++) {
const krb5_crypto_iov *iov = &data[i];
size_t nbytes;
- if (!ENCRYPT_IOV(iov))
+ if (iov_state->got_header ?
+ !ENCRYPT_DATA_IOV(iov) :
+ !ENCRYPT_CONF_IOV(iov))
continue;
- nbytes = iov->data.length - *y;
+ nbytes = iov->data.length - iov_state->data_pos;
if (nbytes > BLOCK_SIZE - j)
nbytes = BLOCK_SIZE - j;
- memcpy(iov->data.data + *y, block + j, nbytes);
+ memcpy(iov->data.data + iov_state->data_pos, block + j, nbytes);
- *y += nbytes;
+ iov_state->data_pos += nbytes;
j += nbytes;
assert(j <= BLOCK_SIZE);
@@ -269,12 +287,20 @@ iov_put_block(const krb5_crypto_iov *data,
if (j == BLOCK_SIZE)
break;
- assert(*y == iov->data.length);
+ assert(iov_state->data_pos == iov->data.length);
+
+ iov_state->data_pos = 0;
+ }
- *y = 0;
+ if (iov_state->got_header == 0 &&
+ data[i].data.length == iov_state->data_pos) {
+ /* Once we have consumed the header, return to start */
+ iov_state->iov_pos = 0;
+ iov_state->data_pos = 0;
+ iov_state->got_header = 1;
}
- *x = i;
+ iov_state->iov_pos = i;
}
static krb5_error_code
@@ -305,27 +331,23 @@ krb5int_aes_encrypt_iov(const krb5_keyblock *key,
nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE;
- if (nblocks == 1) {
- /* XXX Used for DK function, probably will be never used with IOV API,
- * so it's safe to make some arbitrary restrictions here */
- assert(num_data == 1);
- assert(data[0].flags == KRB5_CRYPTO_TYPE_HEADER);
- assert(data[0].data.length == BLOCK_SIZE);
+ assert(nblocks > 1);
- enc(data[0].data.data, data[0].data.data, &ctx);
- } else {
+ {
char blockN2[BLOCK_SIZE]; /* second last */
char blockN1[BLOCK_SIZE]; /* last block */
- size_t input_iov_pos = 0, input_block_pos = 0;
- size_t output_iov_pos = 0, output_block_pos = 0;
+ struct iov_block_state input_pos, output_pos;
+
+ IOV_BLOCK_STATE_INIT(&input_pos);
+ IOV_BLOCK_STATE_INIT(&output_pos);
for (blockno = 0; blockno < nblocks - 2; blockno++) {
char blockN[BLOCK_SIZE];
- iov_get_block(blockN, data, num_data, &input_iov_pos, &input_block_pos);
+ iov_get_block(blockN, data, num_data, &input_pos);
xorblock(tmp, blockN);
enc(tmp2, tmp, &ctx);
- iov_put_block(data, num_data, tmp2, &output_iov_pos, &output_block_pos);
+ iov_put_block(data, num_data, tmp2, &output_pos);
/* Set up for next block. */
memcpy(tmp, tmp2, BLOCK_SIZE);
@@ -336,8 +358,8 @@ krb5int_aes_encrypt_iov(const krb5_keyblock *key,
/* First, get the last two blocks */
memset(blockN1, 0, sizeof(blockN1)); /* pad last block with zeros */
- iov_get_block(blockN2, data, num_data, &input_iov_pos, &input_block_pos);
- iov_get_block(blockN1, data, num_data, &input_iov_pos, &input_block_pos);
+ iov_get_block(blockN2, data, num_data, &input_pos);
+ iov_get_block(blockN1, data, num_data, &input_pos);
/* Encrypt second last block */
xorblock(tmp, blockN2);
@@ -353,8 +375,8 @@ krb5int_aes_encrypt_iov(const krb5_keyblock *key,
memcpy(ivec->data, tmp2, BLOCK_SIZE);
/* Put the last two blocks back into the ivec (reverse order) */
- iov_put_block(data, num_data, blockN1, &output_iov_pos, &output_block_pos);
- iov_put_block(data, num_data, blockN2, &output_iov_pos, &output_block_pos);
+ iov_put_block(data, num_data, blockN1, &output_pos);
+ iov_put_block(data, num_data, blockN2, &output_pos);
}
return 0;
@@ -390,27 +412,23 @@ krb5int_aes_decrypt_iov(const krb5_keyblock *key,
nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE;
- if (nblocks == 1) {
- /* XXX Used for DK function, probably will be never used with IOV API,
- * so it's safe to make some arbitrary restrictions here */
- assert(num_data == 1);
- assert(data[0].flags == KRB5_CRYPTO_TYPE_HEADER);
- assert(data[0].data.length == BLOCK_SIZE);
+ assert(nblocks > 1);
- dec(data[0].data.data, data[0].data.data, &ctx);
- } else {
+ {
char blockN2[BLOCK_SIZE]; /* second last */
char blockN1[BLOCK_SIZE]; /* last block */
- size_t input_iov_pos = 0, input_block_pos = 0;
- size_t output_iov_pos = 0, output_block_pos = 0;
+ struct iov_block_state input_pos, output_pos;
+
+ IOV_BLOCK_STATE_INIT(&input_pos);
+ IOV_BLOCK_STATE_INIT(&output_pos);
for (blockno = 0; blockno < nblocks - 2; blockno++) {
char blockN[BLOCK_SIZE];
- iov_get_block(blockN, data, num_data, &input_iov_pos, &input_block_pos);
+ iov_get_block(blockN, data, num_data, &input_pos);
dec(tmp2, blockN, &ctx);
xorblock(tmp2, tmp);
- iov_put_block(data, num_data, tmp2, &output_iov_pos, &output_block_pos);
+ iov_put_block(data, num_data, tmp2, &output_pos);
memcpy(tmp, blockN, BLOCK_SIZE);
}
@@ -419,8 +437,8 @@ krb5int_aes_decrypt_iov(const krb5_keyblock *key,
/* First, get the last two encrypted blocks */
memset(blockN1, 0, sizeof(blockN1)); /* pad last block with zeros */
- iov_get_block(blockN2, data, num_data, &input_iov_pos, &input_block_pos);
- iov_get_block(blockN1, data, num_data, &input_iov_pos, &input_block_pos);
+ iov_get_block(blockN2, data, num_data, &input_pos);
+ iov_get_block(blockN1, data, num_data, &input_pos);
/* Decrypt second last block */
dec(tmp2, blockN2, &ctx);
@@ -441,8 +459,8 @@ krb5int_aes_decrypt_iov(const krb5_keyblock *key,
memcpy(blockN2, tmp3, BLOCK_SIZE);
/* Put the last two blocks back into the ivec */
- iov_put_block(data, num_data, blockN2, &output_iov_pos, &output_block_pos);
- iov_put_block(data, num_data, blockN1, &output_iov_pos, &output_block_pos);
+ iov_put_block(data, num_data, blockN2, &output_pos);
+ iov_put_block(data, num_data, blockN1, &output_pos);
}
return 0;