diff options
| author | Greg Hudson <ghudson@mit.edu> | 2013-05-06 00:43:27 -0400 |
|---|---|---|
| committer | Greg Hudson <ghudson@mit.edu> | 2013-05-24 14:15:03 -0400 |
| commit | 3b142e5746e7db1939a9cf8095faecfed6222054 (patch) | |
| tree | ef9496f0e47a52e58a88b7f0aac8e3cc77fcf797 /src/lib/crypto/builtin | |
| parent | 48c9a082940373b82d4b8e3c338e9eb9d0d3c3f2 (diff) | |
| download | krb5-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.c | 88 | ||||
| -rw-r--r-- | src/lib/crypto/builtin/des/f_aead.c | 118 | ||||
| -rw-r--r-- | src/lib/crypto/builtin/enc_provider/aes.c | 83 | ||||
| -rw-r--r-- | src/lib/crypto/builtin/enc_provider/camellia.c | 97 | ||||
| -rw-r--r-- | src/lib/crypto/builtin/enc_provider/des.c | 13 | ||||
| -rw-r--r-- | src/lib/crypto/builtin/enc_provider/des3.c | 11 |
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); |
