summaryrefslogtreecommitdiffstats
path: root/src/lib/crypto/builtin
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2013-05-06 00:43:27 -0400
committerGreg Hudson <ghudson@mit.edu>2013-05-24 14:15:03 -0400
commit3b142e5746e7db1939a9cf8095faecfed6222054 (patch)
treeef9496f0e47a52e58a88b7f0aac8e3cc77fcf797 /src/lib/crypto/builtin
parent48c9a082940373b82d4b8e3c338e9eb9d0d3c3f2 (diff)
downloadkrb5-3b142e5746e7db1939a9cf8095faecfed6222054.tar.gz
krb5-3b142e5746e7db1939a9cf8095faecfed6222054.tar.xz
krb5-3b142e5746e7db1939a9cf8095faecfed6222054.zip
Simplify crypto IOV helpers
Expand the concept of an IOV block state into a cursor which remembers the IOV set being iterated over, the block size, and both input and output positions. Eliminate the no-copy inline block getter for now, but provide helpers to grab contiguous chains of blocks from a cursor. Also provide an inline helper to sum the total length of an iov chain.
Diffstat (limited to 'src/lib/crypto/builtin')
-rw-r--r--src/lib/crypto/builtin/des/d3_aead.c88
-rw-r--r--src/lib/crypto/builtin/des/f_aead.c118
-rw-r--r--src/lib/crypto/builtin/enc_provider/aes.c83
-rw-r--r--src/lib/crypto/builtin/enc_provider/camellia.c97
-rw-r--r--src/lib/crypto/builtin/enc_provider/des.c13
-rw-r--r--src/lib/crypto/builtin/enc_provider/des3.c11
6 files changed, 127 insertions, 283 deletions
diff --git a/src/lib/crypto/builtin/des/d3_aead.c b/src/lib/crypto/builtin/des/d3_aead.c
index af34fe9b1..bddf75a47 100644
--- a/src/lib/crypto/builtin/des/d3_aead.c
+++ b/src/lib/crypto/builtin/des/d3_aead.c
@@ -36,11 +36,8 @@ krb5int_des3_cbc_encrypt(krb5_crypto_iov *data, unsigned long num_data,
unsigned DES_INT32 left, right;
const unsigned DES_INT32 *kp1, *kp2, *kp3;
const unsigned char *ip;
- struct iov_block_state input_pos, output_pos;
- unsigned char storage[MIT_DES_BLOCK_LENGTH], *block = NULL, *ptr;
-
- IOV_BLOCK_STATE_INIT(&input_pos);
- IOV_BLOCK_STATE_INIT(&output_pos);
+ struct iov_cursor cursor;
+ unsigned char block[MIT_DES_BLOCK_LENGTH];
/* Get key pointers here. These won't need to be reinitialized. */
kp1 = (const unsigned DES_INT32 *)ks1;
@@ -49,41 +46,28 @@ krb5int_des3_cbc_encrypt(krb5_crypto_iov *data, unsigned long num_data,
/* Initialize left and right with the contents of the initial vector. */
ip = (ivec != NULL) ? ivec : mit_des_zeroblock;
- GET_HALF_BLOCK(left, ip);
- GET_HALF_BLOCK(right, ip);
-
- /* Work the length down 8 bytes at a time. */
- for (;;) {
- unsigned DES_INT32 temp;
-
- if (!krb5int_c_iov_get_block_nocopy(storage, MIT_DES_BLOCK_LENGTH,
- data, num_data, &input_pos, &ptr))
- break;
- block = ptr;
+ left = load_32_be(ip);
+ right = load_32_be(ip + 4);
- /* Decompose this block and xor it with the previous ciphertext. */
- GET_HALF_BLOCK(temp, ptr);
- left ^= temp;
- GET_HALF_BLOCK(temp, ptr);
- right ^= temp;
+ k5_iov_cursor_init(&cursor, data, num_data, MIT_DES_BLOCK_LENGTH, FALSE);
+ while (k5_iov_cursor_get(&cursor, block)) {
+ /* xor this block with the previous ciphertext. */
+ left ^= load_32_be(block);
+ right ^= load_32_be(block + 4);
/* Encrypt what we have and store it back into block. */
DES_DO_ENCRYPT(left, right, kp1);
DES_DO_DECRYPT(left, right, kp2);
DES_DO_ENCRYPT(left, right, kp3);
- ptr = block;
- PUT_HALF_BLOCK(left, ptr);
- PUT_HALF_BLOCK(right, ptr);
+ store_32_be(left, block);
+ store_32_be(right, block + 4);
- krb5int_c_iov_put_block_nocopy(data, num_data, storage,
- MIT_DES_BLOCK_LENGTH, &output_pos,
- block);
+ k5_iov_cursor_put(&cursor, block);
}
- if (ivec != NULL && block != NULL) {
- ptr = ivec;
- PUT_HALF_BLOCK(left, ptr);
- PUT_HALF_BLOCK(right, ptr);
+ if (ivec != NULL) {
+ store_32_be(left, ivec);
+ store_32_be(right, ivec + 4);
}
}
@@ -99,11 +83,8 @@ krb5int_des3_cbc_decrypt(krb5_crypto_iov *data, unsigned long num_data,
const unsigned char *ip;
unsigned DES_INT32 ocipherl, ocipherr;
unsigned DES_INT32 cipherl, cipherr;
- struct iov_block_state input_pos, output_pos;
- unsigned char storage[MIT_DES_BLOCK_LENGTH], *block = NULL, *ptr;
-
- IOV_BLOCK_STATE_INIT(&input_pos);
- IOV_BLOCK_STATE_INIT(&output_pos);
+ struct iov_cursor cursor;
+ unsigned char block[MIT_DES_BLOCK_LENGTH];
/* Get key pointers here. These won't need to be reinitialized. */
kp1 = (const unsigned DES_INT32 *)ks1;
@@ -118,21 +99,14 @@ krb5int_des3_cbc_decrypt(krb5_crypto_iov *data, unsigned long num_data,
/* Prime the old cipher with ivec.*/
ip = (ivec != NULL) ? ivec : mit_des_zeroblock;
- GET_HALF_BLOCK(ocipherl, ip);
- GET_HALF_BLOCK(ocipherr, ip);
-
- /* Work the length down 8 bytes at a time. */
- for (;;) {
- if (!krb5int_c_iov_get_block_nocopy(storage, MIT_DES_BLOCK_LENGTH,
- data, num_data, &input_pos, &ptr))
- break;
- block = ptr;
+ ocipherl = load_32_be(ip);
+ ocipherr = load_32_be(ip + 4);
+ k5_iov_cursor_init(&cursor, data, num_data, MIT_DES_BLOCK_LENGTH, FALSE);
+ while (k5_iov_cursor_get(&cursor, block)) {
/* Split this block into left and right. */
- GET_HALF_BLOCK(left, ptr);
- GET_HALF_BLOCK(right, ptr);
- cipherl = left;
- cipherr = right;
+ cipherl = left = load_32_be(block);
+ cipherr = right = load_32_be(block + 4);
/* Decrypt and xor with the old cipher to get plain text. */
DES_DO_DECRYPT(left, right, kp3);
@@ -142,22 +116,18 @@ krb5int_des3_cbc_decrypt(krb5_crypto_iov *data, unsigned long num_data,
right ^= ocipherr;
/* Store the encrypted halves back into block. */
- ptr = block;
- PUT_HALF_BLOCK(left, ptr);
- PUT_HALF_BLOCK(right, ptr);
+ store_32_be(left, block);
+ store_32_be(right, block + 4);
/* Save current cipher block halves. */
ocipherl = cipherl;
ocipherr = cipherr;
- krb5int_c_iov_put_block_nocopy(data, num_data, storage,
- MIT_DES_BLOCK_LENGTH, &output_pos,
- block);
+ k5_iov_cursor_put(&cursor, block);
}
- if (ivec != NULL && block != NULL) {
- ptr = ivec;
- PUT_HALF_BLOCK(ocipherl, ptr);
- PUT_HALF_BLOCK(ocipherr, ptr);
+ if (ivec != NULL) {
+ store_32_be(ocipherl, ivec);
+ store_32_be(ocipherr, ivec + 4);
}
}
diff --git a/src/lib/crypto/builtin/des/f_aead.c b/src/lib/crypto/builtin/des/f_aead.c
index 5d8028626..71b8dff4d 100644
--- a/src/lib/crypto/builtin/des/f_aead.c
+++ b/src/lib/crypto/builtin/des/f_aead.c
@@ -36,50 +36,34 @@ krb5int_des_cbc_encrypt(krb5_crypto_iov *data, unsigned long num_data,
unsigned DES_INT32 left, right;
const unsigned DES_INT32 *kp;
const unsigned char *ip;
- struct iov_block_state input_pos, output_pos;
- unsigned char storage[MIT_DES_BLOCK_LENGTH], *block = NULL, *ptr;
-
- IOV_BLOCK_STATE_INIT(&input_pos);
- IOV_BLOCK_STATE_INIT(&output_pos);
+ struct iov_cursor cursor;
+ unsigned char block[MIT_DES_BLOCK_LENGTH];
/* Get key pointer here. This won't need to be reinitialized. */
kp = (const unsigned DES_INT32 *)schedule;
/* Initialize left and right with the contents of the initial vector. */
ip = (ivec != NULL) ? ivec : mit_des_zeroblock;
- GET_HALF_BLOCK(left, ip);
- GET_HALF_BLOCK(right, ip);
-
- /* Work the length down 8 bytes at a time. */
- for (;;) {
- unsigned DES_INT32 temp;
-
- if (!krb5int_c_iov_get_block_nocopy(storage, MIT_DES_BLOCK_LENGTH,
- data, num_data, &input_pos, &ptr))
- break;
- block = ptr;
+ left = load_32_be(ip);
+ right = load_32_be(ip + 4);
+ k5_iov_cursor_init(&cursor, data, num_data, MIT_DES_BLOCK_LENGTH, FALSE);
+ while (k5_iov_cursor_get(&cursor, block)) {
/* Decompose this block and xor it with the previous ciphertext. */
- GET_HALF_BLOCK(temp, ptr);
- left ^= temp;
- GET_HALF_BLOCK(temp, ptr);
- right ^= temp;
+ left ^= load_32_be(block);
+ right ^= load_32_be(block + 4);
/* Encrypt what we have and put back into block. */
DES_DO_ENCRYPT(left, right, kp);
- ptr = block;
- PUT_HALF_BLOCK(left, ptr);
- PUT_HALF_BLOCK(right, ptr);
+ store_32_be(left, block);
+ store_32_be(right, block + 4);
- krb5int_c_iov_put_block_nocopy(data, num_data, storage,
- MIT_DES_BLOCK_LENGTH, &output_pos,
- block);
+ k5_iov_cursor_put(&cursor, block);
}
- if (ivec != NULL && block != NULL) {
- ptr = ivec;
- PUT_HALF_BLOCK(left, ptr);
- PUT_HALF_BLOCK(right, ptr);
+ if (ivec != NULL) {
+ store_32_be(left, ivec);
+ store_32_be(right, ivec + 4);
}
}
@@ -93,11 +77,8 @@ krb5int_des_cbc_decrypt(krb5_crypto_iov *data, unsigned long num_data,
const unsigned char *ip;
unsigned DES_INT32 ocipherl, ocipherr;
unsigned DES_INT32 cipherl, cipherr;
- struct iov_block_state input_pos, output_pos;
- unsigned char storage[MIT_DES_BLOCK_LENGTH], *block = NULL, *ptr;
-
- IOV_BLOCK_STATE_INIT(&input_pos);
- IOV_BLOCK_STATE_INIT(&output_pos);
+ struct iov_cursor cursor;
+ unsigned char block[MIT_DES_BLOCK_LENGTH];
/* Get key pointer here. This won't need to be reinitialized. */
kp = (const unsigned DES_INT32 *)schedule;
@@ -110,21 +91,14 @@ krb5int_des_cbc_decrypt(krb5_crypto_iov *data, unsigned long num_data,
/* Prime the old cipher with ivec. */
ip = (ivec != NULL) ? ivec : mit_des_zeroblock;
- GET_HALF_BLOCK(ocipherl, ip);
- GET_HALF_BLOCK(ocipherr, ip);
-
- /* Work the length down 8 bytes at a time. */
- for (;;) {
- if (!krb5int_c_iov_get_block_nocopy(storage, MIT_DES_BLOCK_LENGTH,
- data, num_data, &input_pos, &ptr))
- break;
- block = ptr;
+ ocipherl = load_32_be(ip);
+ ocipherr = load_32_be(ip + 4);
+ k5_iov_cursor_init(&cursor, data, num_data, MIT_DES_BLOCK_LENGTH, FALSE);
+ while (k5_iov_cursor_get(&cursor, block)) {
/* Split this block into left and right. */
- GET_HALF_BLOCK(left, ptr);
- GET_HALF_BLOCK(right, ptr);
- cipherl = left;
- cipherr = right;
+ cipherl = left = load_32_be(block);
+ cipherr = right = load_32_be(block + 4);
/* Decrypt and xor with the old cipher to get plain text. */
DES_DO_DECRYPT(left, right, kp);
@@ -132,23 +106,19 @@ krb5int_des_cbc_decrypt(krb5_crypto_iov *data, unsigned long num_data,
right ^= ocipherr;
/* Store the encrypted halves back into block. */
- ptr = block;
- PUT_HALF_BLOCK(left, ptr);
- PUT_HALF_BLOCK(right, ptr);
+ store_32_be(left, block);
+ store_32_be(right, block + 4);
/* Save current cipher block halves. */
ocipherl = cipherl;
ocipherr = cipherr;
- krb5int_c_iov_put_block_nocopy(data, num_data, storage,
- MIT_DES_BLOCK_LENGTH, &output_pos,
- block);
+ k5_iov_cursor_put(&cursor, block);
}
- if (ivec != NULL && block != NULL) {
- ptr = ivec;
- PUT_HALF_BLOCK(ocipherl, ptr);
- PUT_HALF_BLOCK(ocipherr, ptr);
+ if (ivec != NULL) {
+ store_32_be(ocipherl, ivec);
+ store_32_be(ocipherr, ivec + 4);
}
}
@@ -160,42 +130,30 @@ krb5int_des_cbc_mac(const krb5_crypto_iov *data, unsigned long num_data,
unsigned DES_INT32 left, right;
const unsigned DES_INT32 *kp;
const unsigned char *ip;
- struct iov_block_state input_pos;
- unsigned char storage[MIT_DES_BLOCK_LENGTH], *ptr;
-
- IOV_BLOCK_STATE_INIT(&input_pos);
- input_pos.include_sign_only = 1;
+ struct iov_cursor cursor;
+ unsigned char block[MIT_DES_BLOCK_LENGTH];
/* Get key pointer here. This won't need to be reinitialized. */
kp = (const unsigned DES_INT32 *)schedule;
/* Initialize left and right with the contents of the initial vector. */
ip = (ivec != NULL) ? ivec : mit_des_zeroblock;
- GET_HALF_BLOCK(left, ip);
- GET_HALF_BLOCK(right, ip);
-
- /* Work the length down 8 bytes at a time. */
- for (;;) {
- unsigned DES_INT32 temp;
-
- if (!krb5int_c_iov_get_block_nocopy(storage, MIT_DES_BLOCK_LENGTH,
- data, num_data, &input_pos, &ptr))
- break;
+ left = load_32_be(ip);
+ right = load_32_be(ip + 4);
+ k5_iov_cursor_init(&cursor, data, num_data, MIT_DES_BLOCK_LENGTH, TRUE);
+ while (k5_iov_cursor_get(&cursor, block)) {
/* Decompose this block and xor it with the previous ciphertext. */
- GET_HALF_BLOCK(temp, ptr);
- left ^= temp;
- GET_HALF_BLOCK(temp, ptr);
- right ^= temp;
+ left ^= load_32_be(block);
+ right ^= load_32_be(block + 4);
/* Encrypt what we have. */
DES_DO_ENCRYPT(left, right, kp);
}
/* Output the final ciphertext block. */
- ptr = out;
- PUT_HALF_BLOCK(left, ptr);
- PUT_HALF_BLOCK(right, ptr);
+ store_32_be(left, out);
+ store_32_be(right, out + 4);
}
#if defined(CONFIG_SMALL) && !defined(CONFIG_SMALL_NO_CRYPTO)
diff --git a/src/lib/crypto/builtin/enc_provider/aes.c b/src/lib/crypto/builtin/enc_provider/aes.c
index b46680a9e..280119a2c 100644
--- a/src/lib/crypto/builtin/enc_provider/aes.c
+++ b/src/lib/crypto/builtin/enc_provider/aes.c
@@ -85,9 +85,8 @@ krb5int_aes_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
size_t num_data)
{
unsigned char tmp[BLOCK_SIZE], tmp2[BLOCK_SIZE];
- int nblocks = 0, blockno;
- size_t input_length, i;
- struct iov_block_state input_pos, output_pos;
+ size_t input_length, nblocks, blockno;
+ struct iov_cursor cursor;
if (key->cache == NULL) {
key->cache = malloc(sizeof(struct aes_key_info_cache));
@@ -106,34 +105,25 @@ krb5int_aes_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
else
memset(tmp, 0, BLOCK_SIZE);
- for (i = 0, input_length = 0; i < num_data; i++) {
- krb5_crypto_iov *iov = &data[i];
-
- if (ENCRYPT_IOV(iov))
- input_length += iov->data.length;
- }
-
- IOV_BLOCK_STATE_INIT(&input_pos);
- IOV_BLOCK_STATE_INIT(&output_pos);
+ k5_iov_cursor_init(&cursor, data, num_data, BLOCK_SIZE, FALSE);
+ input_length = iov_total_length(data, num_data, FALSE);
nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE;
if (nblocks == 1) {
- krb5int_c_iov_get_block(tmp, BLOCK_SIZE, data, num_data, &input_pos);
+ k5_iov_cursor_get(&cursor, tmp);
enc(tmp2, tmp, &CACHE(key)->enc_ctx);
- krb5int_c_iov_put_block(data, num_data, tmp2, BLOCK_SIZE, &output_pos);
+ k5_iov_cursor_put(&cursor, tmp2);
} else if (nblocks > 1) {
unsigned char blockN2[BLOCK_SIZE]; /* second last */
unsigned char blockN1[BLOCK_SIZE]; /* last block */
for (blockno = 0; blockno < nblocks - 2; blockno++) {
- unsigned char blockN[BLOCK_SIZE], *block;
+ unsigned char block[BLOCK_SIZE];
- krb5int_c_iov_get_block_nocopy(blockN, BLOCK_SIZE,
- data, num_data, &input_pos, &block);
+ k5_iov_cursor_get(&cursor, block);
xorblock(tmp, block);
enc(block, tmp, &CACHE(key)->enc_ctx);
- krb5int_c_iov_put_block_nocopy(data, num_data, blockN, BLOCK_SIZE,
- &output_pos, block);
+ k5_iov_cursor_put(&cursor, block);
/* Set up for next block. */
memcpy(tmp, block, BLOCK_SIZE);
@@ -143,11 +133,8 @@ krb5int_aes_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
may or may not be incomplete). */
/* First, get the last two blocks */
- memset(blockN1, 0, sizeof(blockN1)); /* pad last block with zeros */
- krb5int_c_iov_get_block(blockN2, BLOCK_SIZE, data, num_data,
- &input_pos);
- krb5int_c_iov_get_block(blockN1, BLOCK_SIZE, data, num_data,
- &input_pos);
+ k5_iov_cursor_get(&cursor, blockN2);
+ k5_iov_cursor_get(&cursor, blockN1);
/* Encrypt second last block */
xorblock(tmp, blockN2);
@@ -161,10 +148,8 @@ krb5int_aes_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
memcpy(blockN1, tmp2, BLOCK_SIZE);
/* Put the last two blocks back into the iovec (reverse order) */
- krb5int_c_iov_put_block(data, num_data, blockN1, BLOCK_SIZE,
- &output_pos);
- krb5int_c_iov_put_block(data, num_data, blockN2, BLOCK_SIZE,
- &output_pos);
+ k5_iov_cursor_put(&cursor, blockN1);
+ k5_iov_cursor_put(&cursor, blockN2);
if (ivec != NULL)
memcpy(ivec->data, blockN1, BLOCK_SIZE);
@@ -178,10 +163,8 @@ krb5int_aes_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
size_t num_data)
{
unsigned char tmp[BLOCK_SIZE], tmp2[BLOCK_SIZE], tmp3[BLOCK_SIZE];
- int nblocks = 0, blockno;
- unsigned int i;
- size_t input_length;
- struct iov_block_state input_pos, output_pos;
+ size_t input_length, nblocks, blockno;
+ struct iov_cursor cursor;
CHECK_SIZES;
@@ -202,47 +185,35 @@ krb5int_aes_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
else
memset(tmp, 0, BLOCK_SIZE);
- for (i = 0, input_length = 0; i < num_data; i++) {
- krb5_crypto_iov *iov = &data[i];
-
- if (ENCRYPT_IOV(iov))
- input_length += iov->data.length;
- }
-
- IOV_BLOCK_STATE_INIT(&input_pos);
- IOV_BLOCK_STATE_INIT(&output_pos);
+ k5_iov_cursor_init(&cursor, data, num_data, BLOCK_SIZE, FALSE);
+ input_length = iov_total_length(data, num_data, FALSE);
nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE;
if (nblocks == 1) {
- krb5int_c_iov_get_block(tmp, BLOCK_SIZE, data, num_data, &input_pos);
+ k5_iov_cursor_get(&cursor, tmp);
dec(tmp2, tmp, &CACHE(key)->dec_ctx);
- krb5int_c_iov_put_block(data, num_data, tmp2, BLOCK_SIZE, &output_pos);
+ k5_iov_cursor_put(&cursor, tmp2);
} else if (nblocks > 1) {
unsigned char blockN2[BLOCK_SIZE]; /* second last */
unsigned char blockN1[BLOCK_SIZE]; /* last block */
for (blockno = 0; blockno < nblocks - 2; blockno++) {
- unsigned char blockN[BLOCK_SIZE], *block;
+ unsigned char block[BLOCK_SIZE];
- krb5int_c_iov_get_block_nocopy(blockN, BLOCK_SIZE,
- data, num_data, &input_pos, &block);
+ k5_iov_cursor_get(&cursor, block);
memcpy(tmp2, block, BLOCK_SIZE);
dec(block, block, &CACHE(key)->dec_ctx);
xorblock(block, tmp);
memcpy(tmp, tmp2, BLOCK_SIZE);
- krb5int_c_iov_put_block_nocopy(data, num_data, blockN, BLOCK_SIZE,
- &output_pos, block);
+ k5_iov_cursor_put(&cursor, block);
}
/* Do last two blocks, the second of which (next-to-last block
of plaintext) may be incomplete. */
/* First, get the last two encrypted blocks */
- memset(blockN1, 0, sizeof(blockN1)); /* pad last block with zeros */
- krb5int_c_iov_get_block(blockN2, BLOCK_SIZE, data, num_data,
- &input_pos);
- krb5int_c_iov_get_block(blockN1, BLOCK_SIZE, data, num_data,
- &input_pos);
+ k5_iov_cursor_get(&cursor, blockN2);
+ k5_iov_cursor_get(&cursor, blockN1);
if (ivec != NULL)
memcpy(ivec->data, blockN2, BLOCK_SIZE);
@@ -263,10 +234,8 @@ krb5int_aes_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
memcpy(blockN1, tmp3, BLOCK_SIZE);
/* Put the last two blocks back into the iovec */
- krb5int_c_iov_put_block(data, num_data, blockN1, BLOCK_SIZE,
- &output_pos);
- krb5int_c_iov_put_block(data, num_data, blockN2, BLOCK_SIZE,
- &output_pos);
+ k5_iov_cursor_put(&cursor, blockN1);
+ k5_iov_cursor_put(&cursor, blockN2);
}
return 0;
diff --git a/src/lib/crypto/builtin/enc_provider/camellia.c b/src/lib/crypto/builtin/enc_provider/camellia.c
index 7a0fbd96e..efba629eb 100644
--- a/src/lib/crypto/builtin/enc_provider/camellia.c
+++ b/src/lib/crypto/builtin/enc_provider/camellia.c
@@ -82,9 +82,8 @@ krb5int_camellia_encrypt(krb5_key key, const krb5_data *ivec,
krb5_crypto_iov *data, size_t num_data)
{
unsigned char tmp[BLOCK_SIZE], tmp2[BLOCK_SIZE];
- int nblocks = 0, blockno;
- size_t input_length, i;
- struct iov_block_state input_pos, output_pos;
+ size_t input_length, nblocks, blockno;
+ struct iov_cursor cursor;
if (key->cache == NULL) {
key->cache = malloc(sizeof(struct camellia_key_info_cache));
@@ -102,34 +101,25 @@ krb5int_camellia_encrypt(krb5_key key, const krb5_data *ivec,
else
memset(tmp, 0, BLOCK_SIZE);
- for (i = 0, input_length = 0; i < num_data; i++) {
- krb5_crypto_iov *iov = &data[i];
-
- if (ENCRYPT_IOV(iov))
- input_length += iov->data.length;
- }
-
- IOV_BLOCK_STATE_INIT(&input_pos);
- IOV_BLOCK_STATE_INIT(&output_pos);
+ k5_iov_cursor_init(&cursor, data, num_data, BLOCK_SIZE, FALSE);
+ input_length = iov_total_length(data, num_data, FALSE);
nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE;
if (nblocks == 1) {
- krb5int_c_iov_get_block(tmp, BLOCK_SIZE, data, num_data, &input_pos);
+ k5_iov_cursor_get(&cursor, tmp);
enc(tmp2, tmp, &CACHE(key)->enc_ctx);
- krb5int_c_iov_put_block(data, num_data, tmp2, BLOCK_SIZE, &output_pos);
+ k5_iov_cursor_put(&cursor, tmp2);
} else if (nblocks > 1) {
unsigned char blockN2[BLOCK_SIZE]; /* second last */
unsigned char blockN1[BLOCK_SIZE]; /* last block */
for (blockno = 0; blockno < nblocks - 2; blockno++) {
- unsigned char blockN[BLOCK_SIZE], *block;
+ unsigned char block[BLOCK_SIZE];
- krb5int_c_iov_get_block_nocopy(blockN, BLOCK_SIZE,
- data, num_data, &input_pos, &block);
+ k5_iov_cursor_get(&cursor, block);
xorblock(tmp, block);
enc(block, tmp, &CACHE(key)->enc_ctx);
- krb5int_c_iov_put_block_nocopy(data, num_data, blockN, BLOCK_SIZE,
- &output_pos, block);
+ k5_iov_cursor_put(&cursor, block);
/* Set up for next block. */
memcpy(tmp, block, BLOCK_SIZE);
@@ -139,11 +129,8 @@ krb5int_camellia_encrypt(krb5_key key, const krb5_data *ivec,
may or may not be incomplete). */
/* First, get the last two blocks */
- memset(blockN1, 0, sizeof(blockN1)); /* pad last block with zeros */
- krb5int_c_iov_get_block(blockN2, BLOCK_SIZE, data, num_data,
- &input_pos);
- krb5int_c_iov_get_block(blockN1, BLOCK_SIZE, data, num_data,
- &input_pos);
+ k5_iov_cursor_get(&cursor, blockN2);
+ k5_iov_cursor_get(&cursor, blockN1);
/* Encrypt second last block */
xorblock(tmp, blockN2);
@@ -157,10 +144,8 @@ krb5int_camellia_encrypt(krb5_key key, const krb5_data *ivec,
memcpy(blockN1, tmp2, BLOCK_SIZE);
/* Put the last two blocks back into the iovec (reverse order) */
- krb5int_c_iov_put_block(data, num_data, blockN1, BLOCK_SIZE,
- &output_pos);
- krb5int_c_iov_put_block(data, num_data, blockN2, BLOCK_SIZE,
- &output_pos);
+ k5_iov_cursor_put(&cursor, blockN1);
+ k5_iov_cursor_put(&cursor, blockN2);
if (ivec != NULL)
memcpy(ivec->data, blockN1, BLOCK_SIZE);
@@ -174,10 +159,8 @@ krb5int_camellia_decrypt(krb5_key key, const krb5_data *ivec,
krb5_crypto_iov *data, size_t num_data)
{
unsigned char tmp[BLOCK_SIZE], tmp2[BLOCK_SIZE], tmp3[BLOCK_SIZE];
- int nblocks = 0, blockno;
- unsigned int i;
- size_t input_length;
- struct iov_block_state input_pos, output_pos;
+ size_t input_length, nblocks, blockno;
+ struct iov_cursor cursor;
if (key->cache == NULL) {
key->cache = malloc(sizeof(struct camellia_key_info_cache));
@@ -196,47 +179,35 @@ krb5int_camellia_decrypt(krb5_key key, const krb5_data *ivec,
else
memset(tmp, 0, BLOCK_SIZE);
- for (i = 0, input_length = 0; i < num_data; i++) {
- krb5_crypto_iov *iov = &data[i];
-
- if (ENCRYPT_IOV(iov))
- input_length += iov->data.length;
- }
-
- IOV_BLOCK_STATE_INIT(&input_pos);
- IOV_BLOCK_STATE_INIT(&output_pos);
+ k5_iov_cursor_init(&cursor, data, num_data, BLOCK_SIZE, FALSE);
+ input_length = iov_total_length(data, num_data, FALSE);
nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE;
if (nblocks == 1) {
- krb5int_c_iov_get_block(tmp, BLOCK_SIZE, data, num_data, &input_pos);
+ k5_iov_cursor_get(&cursor, tmp);
dec(tmp2, tmp, &CACHE(key)->dec_ctx);
- krb5int_c_iov_put_block(data, num_data, tmp2, BLOCK_SIZE, &output_pos);
+ k5_iov_cursor_put(&cursor, tmp2);
} else if (nblocks > 1) {
unsigned char blockN2[BLOCK_SIZE]; /* second last */
unsigned char blockN1[BLOCK_SIZE]; /* last block */
for (blockno = 0; blockno < nblocks - 2; blockno++) {
- unsigned char blockN[BLOCK_SIZE], *block;
+ unsigned char block[BLOCK_SIZE];
- krb5int_c_iov_get_block_nocopy(blockN, BLOCK_SIZE,
- data, num_data, &input_pos, &block);
+ k5_iov_cursor_get(&cursor, block);
memcpy(tmp2, block, BLOCK_SIZE);
dec(block, block, &CACHE(key)->dec_ctx);
xorblock(block, tmp);
memcpy(tmp, tmp2, BLOCK_SIZE);
- krb5int_c_iov_put_block_nocopy(data, num_data, blockN, BLOCK_SIZE,
- &output_pos, block);
+ k5_iov_cursor_put(&cursor, block);
}
/* Do last two blocks, the second of which (next-to-last block
of plaintext) may be incomplete. */
/* First, get the last two encrypted blocks */
- memset(blockN1, 0, sizeof(blockN1)); /* pad last block with zeros */
- krb5int_c_iov_get_block(blockN2, BLOCK_SIZE, data, num_data,
- &input_pos);
- krb5int_c_iov_get_block(blockN1, BLOCK_SIZE, data, num_data,
- &input_pos);
+ k5_iov_cursor_get(&cursor, blockN2);
+ k5_iov_cursor_get(&cursor, blockN1);
if (ivec != NULL)
memcpy(ivec->data, blockN2, BLOCK_SIZE);
@@ -257,10 +228,8 @@ krb5int_camellia_decrypt(krb5_key key, const krb5_data *ivec,
memcpy(blockN1, tmp3, BLOCK_SIZE);
/* Put the last two blocks back into the iovec */
- krb5int_c_iov_put_block(data, num_data, blockN1, BLOCK_SIZE,
- &output_pos);
- krb5int_c_iov_put_block(data, num_data, blockN2, BLOCK_SIZE,
- &output_pos);
+ k5_iov_cursor_put(&cursor, blockN1);
+ k5_iov_cursor_put(&cursor, blockN2);
}
return 0;
@@ -272,8 +241,8 @@ krb5int_camellia_cbc_mac(krb5_key key, const krb5_crypto_iov *data,
krb5_data *output)
{
camellia_ctx ctx;
- unsigned char blockY[BLOCK_SIZE];
- struct iov_block_state iov_state;
+ unsigned char blockY[BLOCK_SIZE], blockB[BLOCK_SIZE];
+ struct iov_cursor cursor;
if (output->length < BLOCK_SIZE)
return KRB5_BAD_MSIZE;
@@ -287,14 +256,8 @@ krb5int_camellia_cbc_mac(krb5_key key, const krb5_crypto_iov *data,
else
memset(blockY, 0, BLOCK_SIZE);
- IOV_BLOCK_STATE_INIT(&iov_state);
- for (;;) {
- unsigned char blockB[BLOCK_SIZE];
-
- if (!krb5int_c_iov_get_block(blockB, BLOCK_SIZE, data, num_data,
- &iov_state))
- break;
-
+ k5_iov_cursor_init(&cursor, data, num_data, BLOCK_SIZE, FALSE);
+ while (k5_iov_cursor_get(&cursor, blockB)) {
xorblock(blockB, blockY);
if (camellia_enc_blk(blockB, blockY, &ctx) != camellia_good)
abort();
diff --git a/src/lib/crypto/builtin/enc_provider/des.c b/src/lib/crypto/builtin/enc_provider/des.c
index 72a3ffc3b..30b8229f8 100644
--- a/src/lib/crypto/builtin/enc_provider/des.c
+++ b/src/lib/crypto/builtin/enc_provider/des.c
@@ -33,18 +33,11 @@ validate_and_schedule(krb5_key key, const krb5_data *ivec,
const krb5_crypto_iov *data, size_t num_data,
mit_des_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->keyblock.length != 8)
return KRB5_BAD_KEYSIZE;
- if (input_length % 8 != 0 || (ivec != NULL && ivec->length != 8))
+ if (iov_total_length(data, num_data, FALSE) % 8 != 0)
+ return KRB5_BAD_MSIZE;
+ if (ivec != NULL && ivec->length != 8)
return KRB5_BAD_MSIZE;
switch (mit_des_key_sched(key->keyblock.contents, schedule)) {
diff --git a/src/lib/crypto/builtin/enc_provider/des3.c b/src/lib/crypto/builtin/enc_provider/des3.c
index 793db5e56..9b8244223 100644
--- a/src/lib/crypto/builtin/enc_provider/des3.c
+++ b/src/lib/crypto/builtin/enc_provider/des3.c
@@ -33,18 +33,9 @@ validate_and_schedule(krb5_key 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->keyblock.length != 24)
return(KRB5_BAD_KEYSIZE);
- if ((input_length%8) != 0)
+ if (iov_total_length(data, num_data, FALSE) % 8 != 0)
return(KRB5_BAD_MSIZE);
if (ivec && (ivec->length != 8))
return(KRB5_BAD_MSIZE);