diff options
author | Sam Hartman <hartmans@mit.edu> | 2008-12-01 16:42:18 +0000 |
---|---|---|
committer | Sam Hartman <hartmans@mit.edu> | 2008-12-01 16:42:18 +0000 |
commit | 74844f649c7c77c2b96bc9ab8a1b22707138d58d (patch) | |
tree | ae2e0f1c2ab078d1d29d4480e4699d345c7193a0 | |
parent | 5ff2db3b6cfa52dc5f8776d0c2a7aaebee18ef68 (diff) | |
download | krb5-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.h | 7 | ||||
-rw-r--r-- | src/lib/crypto/des/d3_aead.c | 97 | ||||
-rw-r--r-- | src/lib/crypto/dk/dk_aead.c | 6 | ||||
-rw-r--r-- | src/lib/crypto/enc_provider/aes.c | 122 |
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; |