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 | |
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')
-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 | ||||
-rw-r--r-- | src/lib/crypto/krb/aead.c | 86 | ||||
-rw-r--r-- | src/lib/crypto/krb/cmac.c | 18 | ||||
-rw-r--r-- | src/lib/crypto/krb/crypto_int.h | 260 | ||||
-rw-r--r-- | src/lib/crypto/krb/enc_old.c | 10 | ||||
-rw-r--r-- | src/lib/crypto/nss/enc_provider/enc_gen.c | 93 | ||||
-rw-r--r-- | src/lib/crypto/openssl/enc_provider/aes.c | 77 | ||||
-rw-r--r-- | src/lib/crypto/openssl/enc_provider/camellia.c | 93 | ||||
-rw-r--r-- | src/lib/crypto/openssl/enc_provider/des.c | 54 | ||||
-rw-r--r-- | src/lib/crypto/openssl/enc_provider/des3.c | 42 |
15 files changed, 375 insertions, 768 deletions
diff --git a/src/lib/crypto/builtin/des/d3_aead.c b/src/lib/crypto/builtin/des/d3_aead.c index af34fe9b1e..bddf75a474 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 5d80286269..71b8dff4d4 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 b46680a9e0..280119a2cc 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 7a0fbd96ef..efba629ebe 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 72a3ffc3b7..30b8229f8c 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 793db5e563..9b82442236 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); diff --git a/src/lib/crypto/krb/aead.c b/src/lib/crypto/krb/aead.c index 7bfed4b1e0..935125d9d0 100644 --- a/src/lib/crypto/krb/aead.c +++ b/src/lib/crypto/krb/aead.c @@ -135,3 +135,89 @@ krb5int_c_padding_length(const struct krb5_keytypes *ktp, size_t data_length) else return padding - (data_length % padding); } + +/* Return the next iov (starting from ind) which cursor should process, or + * cursor->iov_count if there are none remaining. */ +static size_t +next_iov_to_process(struct iov_cursor *cursor, size_t ind) +{ + krb5_crypto_iov *iov; + + for (; ind < cursor->iov_count; ind++) { + iov = &cursor->iov[ind]; + if (cursor->signing ? SIGN_IOV(iov) : ENCRYPT_IOV(iov)) + break; + } + return ind; +} + +void +k5_iov_cursor_init(struct iov_cursor *cursor, const krb5_crypto_iov *iov, + size_t count, size_t block_size, krb5_boolean signing) +{ + cursor->iov = iov; + cursor->iov_count = count; + cursor->block_size = block_size; + cursor->signing = signing; + cursor->in_iov = next_iov_to_process(cursor, 0); + cursor->out_iov = cursor->in_iov; + cursor->in_pos = cursor->out_pos = 0; +} + +/* Fetch one block from cursor's input position. */ +krb5_boolean +k5_iov_cursor_get(struct iov_cursor *cursor, unsigned char *block) +{ + size_t nbytes, bsz = cursor->block_size, remain = cursor->block_size; + const krb5_crypto_iov *iov; + + remain = cursor->block_size; + while (remain > 0 && cursor->in_iov < cursor->iov_count) { + iov = &cursor->iov[cursor->in_iov]; + + nbytes = iov->data.length - cursor->in_pos; + if (nbytes > remain) + nbytes = remain; + + memcpy(block + bsz - remain, iov->data.data + cursor->in_pos, nbytes); + cursor->in_pos += nbytes; + remain -= nbytes; + + if (cursor->in_pos == iov->data.length) { + cursor->in_iov = next_iov_to_process(cursor, cursor->in_iov + 1); + cursor->in_pos = 0; + } + } + + if (remain == bsz) + return FALSE; + if (remain > 0) + memset(block + bsz - remain, 0, remain); + return TRUE; +} + +/* Write a block to a cursor's output position. */ +void +k5_iov_cursor_put(struct iov_cursor *cursor, unsigned char *block) +{ + size_t nbytes, bsz = cursor->block_size, remain = cursor->block_size; + const krb5_crypto_iov *iov; + + remain = cursor->block_size; + while (remain > 0 && cursor->out_iov < cursor->iov_count) { + iov = &cursor->iov[cursor->out_iov]; + + nbytes = iov->data.length - cursor->out_pos; + if (nbytes > remain) + nbytes = remain; + + memcpy(iov->data.data + cursor->out_pos, block + bsz - remain, nbytes); + cursor->out_pos += nbytes; + remain -= nbytes; + + if (cursor->out_pos == iov->data.length) { + cursor->out_iov = next_iov_to_process(cursor, cursor->out_iov + 1); + cursor->out_pos = 0; + } + } +} diff --git a/src/lib/crypto/krb/cmac.c b/src/lib/crypto/krb/cmac.c index 2e220c5d56..066b534d1b 100644 --- a/src/lib/crypto/krb/cmac.c +++ b/src/lib/crypto/krb/cmac.c @@ -145,8 +145,8 @@ krb5int_cmac_checksum(const struct krb5_enc_provider *enc, krb5_key key, unsigned char input[BLOCK_SIZE]; unsigned int n, i, flag; krb5_error_code ret; - struct iov_block_state iov_state; - unsigned int length; + struct iov_cursor cursor; + size_t length; krb5_crypto_iov iov[1]; krb5_data d; @@ -155,12 +155,7 @@ krb5int_cmac_checksum(const struct krb5_enc_provider *enc, krb5_key key, if (enc->block_size != BLOCK_SIZE) return KRB5_BAD_MSIZE; - for (i = 0, length = 0; i < num_data; i++) { - const krb5_crypto_iov *piov = &data[i]; - - if (SIGN_IOV(piov)) - length += piov->data.length; - } + length = iov_total_length(data, num_data, TRUE); /* Step 1. */ ret = generate_subkey(enc, key, K1, K2); @@ -186,10 +181,9 @@ krb5int_cmac_checksum(const struct krb5_enc_provider *enc, krb5_key key, d = make_data(Y, BLOCK_SIZE); /* Step 6 (all but last block). */ - IOV_BLOCK_STATE_INIT(&iov_state); - iov_state.include_sign_only = 1; + k5_iov_cursor_init(&cursor, data, num_data, BLOCK_SIZE, TRUE); for (i = 0; i < n - 1; i++) { - krb5int_c_iov_get_block(input, BLOCK_SIZE, data, num_data, &iov_state); + k5_iov_cursor_get(&cursor, input); ret = enc->cbc_mac(key, iov, 1, &d, &d); if (ret != 0) @@ -197,7 +191,7 @@ krb5int_cmac_checksum(const struct krb5_enc_provider *enc, krb5_key key, } /* Step 4. */ - krb5int_c_iov_get_block(input, BLOCK_SIZE, data, num_data, &iov_state); + k5_iov_cursor_get(&cursor, input); if (flag) { /* last block is complete block */ xor_128(input, K1, M_last); diff --git a/src/lib/crypto/krb/crypto_int.h b/src/lib/crypto/krb/crypto_int.h index 01090d0068..c2c6344bc8 100644 --- a/src/lib/crypto/krb/crypto_int.h +++ b/src/lib/crypto/krb/crypto_int.h @@ -381,20 +381,17 @@ void krb5int_default_free_state(krb5_data *state); #define SIGN_IOV(_iov) (ENCRYPT_IOV(_iov) || \ (_iov)->flags == KRB5_CRYPTO_TYPE_SIGN_ONLY ) -struct iov_block_state { - size_t iov_pos; /* index into iov array */ - size_t data_pos; /* index into iov contents */ - unsigned int ignore_header : 1; /* have/should we process HEADER */ - unsigned int include_sign_only : 1; /* should we process SIGN_ONLY blocks */ - unsigned int pad_to_boundary : 1; /* should we zero fill blocks until next buffer */ +struct iov_cursor { + const krb5_crypto_iov *iov; /* iov array we are iterating over */ + size_t iov_count; /* size of iov array */ + size_t block_size; /* size of blocks we will be obtaining */ + krb5_boolean signing; /* should we process SIGN_ONLY blocks */ + size_t in_iov; /* read index into iov array */ + size_t in_pos; /* read index into iov contents */ + size_t out_iov; /* write index into iov array */ + size_t out_pos; /* write index into iov contents */ }; -#define IOV_BLOCK_STATE_INIT(_state) ((_state)->iov_pos = \ - (_state)->data_pos = \ - (_state)->ignore_header = \ - (_state)->include_sign_only = \ - (_state)->pad_to_boundary = 0) - krb5_crypto_iov *krb5int_c_locate_iov(krb5_crypto_iov *data, size_t num_data, krb5_cryptotype type); @@ -408,6 +405,14 @@ krb5_error_code krb5int_c_iov_decrypt_stream(const struct krb5_keytypes *ktp, unsigned int krb5int_c_padding_length(const struct krb5_keytypes *ktp, size_t data_length); +void k5_iov_cursor_init(struct iov_cursor *cursor, const krb5_crypto_iov *iov, + size_t count, size_t block_size, krb5_boolean signing); + +krb5_boolean k5_iov_cursor_get(struct iov_cursor *cursor, + unsigned char *block); + +void k5_iov_cursor_put(struct iov_cursor *cursor, unsigned char *block); + /*** Crypto module declarations ***/ /* Modules must implement the following enc_providers and hash_providers: */ @@ -580,225 +585,50 @@ encrypt_block(const struct krb5_enc_provider *enc, krb5_key key, return enc->encrypt(key, 0, &iov, 1); } -/* Decide whether to process an IOV block. */ -static inline int -process_block_p(const krb5_crypto_iov *data, size_t num_data, - struct iov_block_state *iov_state, size_t i) -{ - const krb5_crypto_iov *iov = &data[i]; - int process_block; - - switch (iov->flags) { - case KRB5_CRYPTO_TYPE_SIGN_ONLY: - process_block = iov_state->include_sign_only; - break; - case KRB5_CRYPTO_TYPE_PADDING: - process_block = (iov_state->pad_to_boundary == 0); - break; - case KRB5_CRYPTO_TYPE_HEADER: - process_block = (iov_state->ignore_header == 0); - break; - case KRB5_CRYPTO_TYPE_DATA: - process_block = 1; - break; - default: - process_block = 0; - break; - } - - return process_block; -} - -/* - * Returns TRUE if, having reached the end of the current buffer, - * we should pad the rest of the block with zeros. - */ -static inline int -pad_to_boundary_p(const krb5_crypto_iov *data, - size_t num_data, - struct iov_block_state *iov_state, - size_t i, - size_t j) -{ - /* If the pad_to_boundary flag is unset, return FALSE */ - if (iov_state->pad_to_boundary == 0) - return 0; - - /* If we haven't got any data, we need to get some */ - if (j == 0) - return 0; - - /* No boundary between adjacent buffers marked for processing */ - if (data[iov_state->iov_pos].flags == data[i].flags) - return 0; - - return 1; -} - -/* - * Retrieve a block from the IOV. If p is non-NULL and the next block is - * completely contained within the current buffer, then *p will contain an - * alias into the buffer; otherwise, a copy will be made into storage. - * - * After calling this function, encrypt the returned block and then call - * krb5int_c_iov_put_block_nocopy() (with a separate output cursor). If - * p was non-NULL on the call to get_block(), then pass that pointer in. - */ -static inline krb5_boolean -krb5int_c_iov_get_block_nocopy(unsigned char *storage, - size_t block_size, - const krb5_crypto_iov *data, - size_t num_data, - struct iov_block_state *iov_state, - unsigned char **p) +/* Return the total length of the to-be-signed or to-be-encrypted buffers in an + * iov chain. */ +static inline size_t +iov_total_length(const krb5_crypto_iov *data, size_t num_data, + krb5_boolean signing) { - size_t i, j = 0; - - if (p != NULL) - *p = storage; - - for (i = iov_state->iov_pos; i < num_data; i++) { - const krb5_crypto_iov *iov = &data[i]; - size_t nbytes; - - if (!process_block_p(data, num_data, iov_state, i)) - continue; - - if (pad_to_boundary_p(data, num_data, iov_state, i, j)) - break; - - iov_state->iov_pos = i; - - nbytes = iov->data.length - iov_state->data_pos; - if (nbytes > block_size - j) - nbytes = block_size - j; - - /* - * If we can return a pointer into a complete block, then do so. - */ - if (p != NULL && j == 0 && nbytes == block_size) { - *p = (unsigned char *)iov->data.data + iov_state->data_pos; - } else { - memcpy(storage + j, iov->data.data + iov_state->data_pos, nbytes); - } + size_t i, total = 0; - iov_state->data_pos += nbytes; - j += nbytes; - - assert(j <= block_size); - - if (j == block_size) - break; - - assert(iov_state->data_pos == iov->data.length); - - iov_state->data_pos = 0; + for (i = 0; i < num_data; i++) { + if (signing ? SIGN_IOV(&data[i]) : ENCRYPT_IOV(&data[i])) + total += data[i].data.length; } - - iov_state->iov_pos = i; - - if (j == 0) - return FALSE; - else if (j != block_size) - memset(storage + j, 0, block_size - j); - - return TRUE; + return total; } /* - * Store a block retrieved with krb5int_c_iov_get_block_no_copy if - * necessary, and advance the output cursor. + * Return the number of contiguous blocks available within the current input + * IOV of the cursor c, so that the caller can do in-place encryption. + * Do not call if c might be exhausted. */ -static inline krb5_boolean -krb5int_c_iov_put_block_nocopy(const krb5_crypto_iov *data, - size_t num_data, - unsigned char *storage, - size_t block_size, - struct iov_block_state *iov_state, - unsigned char *p) +static inline size_t +iov_cursor_contig_blocks(struct iov_cursor *c) { - size_t i, j = 0; - - assert(p != NULL); - - for (i = iov_state->iov_pos; i < num_data; i++) { - const krb5_crypto_iov *iov = &data[i]; - size_t nbytes; - - if (!process_block_p(data, num_data, iov_state, i)) - continue; - - if (pad_to_boundary_p(data, num_data, iov_state, i, j)) - break; - - iov_state->iov_pos = i; - - nbytes = iov->data.length - iov_state->data_pos; - if (nbytes > block_size - j) - nbytes = block_size - j; - - /* - * If we had previously returned a pointer into a complete block, - * then no action is required. - */ - if (p == storage) { - memcpy(iov->data.data + iov_state->data_pos, storage + j, nbytes); - } else { - /* Ensure correctly paired with a call to get_block_nocopy(). */ - assert(j == 0); - assert(nbytes == 0 || nbytes == block_size); - } - - iov_state->data_pos += nbytes; - j += nbytes; - - assert(j <= block_size); - - if (j == block_size) - break; - - assert(iov_state->data_pos == iov->data.length); - - iov_state->data_pos = 0; - } - - iov_state->iov_pos = i; - -#ifdef DEBUG_IOV - dump_block("put_block", i, j, p, block_size); -#endif - - return (iov_state->iov_pos < num_data); + return (c->iov[c->in_iov].data.length - c->in_pos) / c->block_size; } -/* - * A wrapper for krb5int_c_iov_get_block_nocopy() that always makes - * a copy. - */ -static inline krb5_boolean -krb5int_c_iov_get_block(unsigned char *block, - size_t block_size, - const krb5_crypto_iov *data, - size_t num_data, - struct iov_block_state *iov_state) +/* Return the current input pointer within the cursor c. Do not call if c + * might be exhausted. */ +static inline unsigned char * +iov_cursor_ptr(struct iov_cursor *c) { - return krb5int_c_iov_get_block_nocopy(block, block_size, data, num_data, - iov_state, NULL); + return (unsigned char *)&c->iov[c->in_iov].data.data[c->in_pos]; } /* - * A wrapper for krb5int_c_iov_put_block_nocopy() that always copies - * the block. + * Advance the input and output pointers of c by nblocks blocks. nblocks must + * not be greater than the return value of iov_cursor_contig_blocks, and the + * input and output positions must be identical. */ -static inline krb5_boolean -krb5int_c_iov_put_block(const krb5_crypto_iov *data, - size_t num_data, - unsigned char *block, - size_t block_size, - struct iov_block_state *iov_state) +static inline void +iov_cursor_advance(struct iov_cursor *c, size_t nblocks) { - return krb5int_c_iov_put_block_nocopy(data, num_data, block, block_size, - iov_state, block); + c->in_pos += nblocks * c->block_size; + c->out_pos += nblocks * c->block_size; } #endif /* CRYPTO_INT_H */ diff --git a/src/lib/crypto/krb/enc_old.c b/src/lib/crypto/krb/enc_old.c index b44a3994f0..a40f709425 100644 --- a/src/lib/crypto/krb/enc_old.c +++ b/src/lib/crypto/krb/enc_old.c @@ -130,17 +130,9 @@ krb5int_old_decrypt(const struct krb5_keytypes *ktp, krb5_key key, krb5_crypto_iov *header, *trailer; krb5_data checksum, crcivec = empty_data(); char *saved_checksum = NULL; - size_t i; - unsigned int cipherlen = 0; /* Check that the input data is correctly padded. */ - for (i = 0; i < num_data; i++) { - const krb5_crypto_iov *iov = &data[i]; - - if (ENCRYPT_IOV(iov)) - cipherlen += iov->data.length; - } - if (cipherlen % enc->block_size != 0) + if (iov_total_length(data, num_data, FALSE) % enc->block_size != 0) return KRB5_BAD_MSIZE; header = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_HEADER); diff --git a/src/lib/crypto/nss/enc_provider/enc_gen.c b/src/lib/crypto/nss/enc_provider/enc_gen.c index dea22f8466..7022a78eed 100644 --- a/src/lib/crypto/nss/enc_provider/enc_gen.c +++ b/src/lib/crypto/nss/enc_provider/enc_gen.c @@ -172,35 +172,25 @@ k5_nss_gen_block_iov(krb5_key krb_key, CK_MECHANISM_TYPE mech, PK11Context *ctx = NULL; SECStatus rv; SECItem *param = NULL; - struct iov_block_state input_pos, output_pos; - unsigned char storage[MAX_BLOCK_SIZE]; + struct iov_cursor cursor; + unsigned char block[MAX_BLOCK_SIZE]; unsigned char iv0[MAX_BLOCK_SIZE]; - unsigned char *ptr = NULL,*lastptr = NULL; + unsigned char *lastptr = NULL; SECItem iv; size_t blocksize; int length = 0; int lastblock = -1; int currentblock; - IOV_BLOCK_STATE_INIT(&input_pos); - IOV_BLOCK_STATE_INIT(&output_pos); - blocksize = PK11_GetBlockSize(mech, NULL); - assert(blocksize <= sizeof(storage)); + assert(blocksize <= sizeof(block)); if (ivec && ivec->data) { iv.data = (unsigned char *)ivec->data; iv.len = ivec->length; if (operation == CKA_DECRYPT) { - int i, inputlength; - /* Count the blocks so we know which block is last. */ - for (i = 0, inputlength = 0; i < (int)num_data; i++) { - krb5_crypto_iov *iov = &data[i]; - - if (ENCRYPT_IOV(iov)) - inputlength += iov->data.length; - } + int inputlength = iov_total_length(data, num_data, FALSE); lastblock = (inputlength/blocksize) -1; } } else { @@ -216,26 +206,25 @@ k5_nss_gen_block_iov(krb5_key krb_key, CK_MECHANISM_TYPE mech, goto done; } + k5_iov_cursor_init(&cursor, data, num_data, blocksize, FALSE); for (currentblock = 0;;currentblock++) { - if (!krb5int_c_iov_get_block_nocopy(storage, blocksize, data, num_data, - &input_pos, &ptr)) + if (!k5_iov_cursor_get(&cursor, block)) break; lastptr = NULL; /* only set if we are decrypting */ if (lastblock == currentblock) - memcpy(ivec->data, ptr, blocksize); + memcpy(ivec->data, block, blocksize); - rv = PK11_CipherOp(ctx, ptr, &length, blocksize, ptr, blocksize); + rv = PK11_CipherOp(ctx, block, &length, blocksize, block, blocksize); if (rv != SECSuccess) { ret = k5_nss_map_last_error(); break; } - lastptr = ptr; - krb5int_c_iov_put_block_nocopy(data, num_data, storage, blocksize, - &output_pos, ptr); + lastptr = block; + k5_iov_cursor_put(&cursor, block); } if (lastptr && ivec && ivec->data && operation == CKA_ENCRYPT) { @@ -349,26 +338,22 @@ k5_nss_gen_cts_iov(krb5_key krb_key, CK_MECHANISM_TYPE mech, PK11Context *ctx = NULL; SECStatus rv; SECItem *param = NULL; - struct iov_block_state input_pos, output_pos; - unsigned char storage[MAX_BLOCK_SIZE]; + struct iov_cursor cursor; + unsigned char block[MAX_BLOCK_SIZE]; unsigned char recover1[MAX_BLOCK_SIZE]; unsigned char recover2[MAX_BLOCK_SIZE]; unsigned char block1[MAX_BLOCK_SIZE]; unsigned char block2[MAX_BLOCK_SIZE]; unsigned char iv0[MAX_BLOCK_SIZE]; - unsigned char *ptr = NULL; SECItem iv; size_t blocksize; size_t bulk_length, remainder; size_t input_length, lastblock; size_t length; - int i, len; - - IOV_BLOCK_STATE_INIT(&input_pos); - IOV_BLOCK_STATE_INIT(&output_pos); + int len; blocksize = PK11_GetBlockSize(mech, NULL); - assert(blocksize <= sizeof(storage)); + assert(blocksize <= sizeof(block)); if (ivec) { iv.data = (unsigned char *)ivec->data; @@ -380,12 +365,7 @@ k5_nss_gen_cts_iov(krb5_key krb_key, CK_MECHANISM_TYPE mech, } param = PK11_ParamFromIV(mech, &iv); - for (i = 0, input_length = 0; i < (int)num_data; i++) { - krb5_crypto_iov *iov = &data[i]; - - if (ENCRYPT_IOV(iov)) - input_length += iov->data.length; - } + input_length = iov_total_length(data, num_data, FALSE); /* Must be at least a block or we fail. */ if (input_length < blocksize) { ret = EINVAL; @@ -429,48 +409,44 @@ k5_nss_gen_cts_iov(krb5_key krb_key, CK_MECHANISM_TYPE mech, } } } + k5_iov_cursor_init(&cursor, data, num_data, blocksize, FALSE); for (length = 0; length < lastblock; length += blocksize) { - if (!krb5int_c_iov_get_block_nocopy(storage, blocksize, data, num_data, - &input_pos, &ptr)) + if (!k5_iov_cursor_get(&cursor, block)) break; - rv = PK11_CipherOp(ctx, ptr, &len, blocksize, ptr, blocksize); + rv = PK11_CipherOp(ctx, block, &len, blocksize, block, blocksize); if (rv != SECSuccess) { ret = k5_nss_map_last_error(); break; } - krb5int_c_iov_put_block_nocopy(data, num_data, storage, blocksize, - &output_pos, ptr); + k5_iov_cursor_put(&cursor, block); } if (remainder) { if (operation == CKA_DECRYPT) { if (bulk_length > blocksize) { /* we need to save cn-2 */ - if (!krb5int_c_iov_get_block_nocopy(storage, blocksize, data, - num_data, &input_pos, - &ptr)) + if (!k5_iov_cursor_get(&cursor, block)) goto done; /* shouldn't happen */ /* save cn-2 */ - memcpy(recover1, ptr, blocksize); - memcpy(recover2, ptr, blocksize); + memcpy(recover1, block, blocksize); + memcpy(recover2, block, blocksize); /* now process it as normal */ - rv = PK11_CipherOp(ctx, ptr, &len, blocksize, ptr, blocksize); + rv = PK11_CipherOp(ctx, block, &len, blocksize, block, + blocksize); if (rv != SECSuccess) { ret = k5_nss_map_last_error(); goto done; } - krb5int_c_iov_put_block_nocopy(data, num_data, storage, - blocksize, &output_pos, ptr); + k5_iov_cursor_put(&cursor, block); } } /* fetch the last 2 blocks */ - memset(block1, 0, blocksize); /* last block, could be partial */ - krb5int_c_iov_get_block(block2, blocksize, data, num_data, &input_pos); - krb5int_c_iov_get_block(block1, remainder, data, num_data, &input_pos); + k5_iov_cursor_get(&cursor, block2); + k5_iov_cursor_get(&cursor, block1); if (operation == CKA_DECRYPT) { /* recover1 and recover2 are xor values to recover the true * underlying data of the last 2 decrypts. This keeps us from @@ -518,8 +494,8 @@ k5_nss_gen_cts_iov(krb5_key krb_key, CK_MECHANISM_TYPE mech, memcpy(ivec->data, block1, blocksize); } } - krb5int_c_iov_put_block(data,num_data, block1, blocksize, &output_pos); - krb5int_c_iov_put_block(data,num_data, block2, remainder, &output_pos); + k5_iov_cursor_put(&cursor, block1); + k5_iov_cursor_put(&cursor, block2); } done: @@ -541,7 +517,7 @@ k5_nss_gen_cbcmac_iov(krb5_key krb_key, CK_MECHANISM_TYPE mech, PK11Context *ctx = NULL; SECStatus rv; SECItem *param = NULL; - struct iov_block_state input_pos, output_pos; + struct iov_cursor cursor; unsigned char block[MAX_BLOCK_SIZE], *lastblock; unsigned char iv0[MAX_BLOCK_SIZE]; SECItem iv; @@ -549,9 +525,6 @@ k5_nss_gen_cbcmac_iov(krb5_key krb_key, CK_MECHANISM_TYPE mech, int length = 0; int currentblock; - IOV_BLOCK_STATE_INIT(&input_pos); - IOV_BLOCK_STATE_INIT(&output_pos); - blocksize = PK11_GetBlockSize(mech, NULL); assert(blocksize <= sizeof(block)); if (output->length < blocksize) @@ -574,9 +547,9 @@ k5_nss_gen_cbcmac_iov(krb5_key krb_key, CK_MECHANISM_TYPE mech, } lastblock = iv.data; + k5_iov_cursor_init(&cursor, data, num_data, blocksize, FALSE); for (currentblock = 0;;currentblock++) { - if (!krb5int_c_iov_get_block(block, blocksize, data, num_data, - &input_pos)) + if (!k5_iov_cursor_get(&cursor, block)) break; rv = PK11_CipherOp(ctx, block, &length, blocksize, block, blocksize); if (rv != SECSuccess) { diff --git a/src/lib/crypto/openssl/enc_provider/aes.c b/src/lib/crypto/openssl/enc_provider/aes.c index ced93f7426..8afa1a7579 100644 --- a/src/lib/crypto/openssl/enc_provider/aes.c +++ b/src/lib/crypto/openssl/enc_provider/aes.c @@ -66,7 +66,7 @@ cbc_enc(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, int ret, olen = BLOCK_SIZE; unsigned char iblock[BLOCK_SIZE], oblock[BLOCK_SIZE]; EVP_CIPHER_CTX ciph_ctx; - struct iov_block_state input_pos, output_pos; + struct iov_cursor cursor; EVP_CIPHER_CTX_init(&ciph_ctx); ret = EVP_EncryptInit_ex(&ciph_ctx, map_mode(key->keyblock.length), @@ -74,15 +74,12 @@ cbc_enc(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, if (ret == 0) return KRB5_CRYPTO_INTERNAL; - IOV_BLOCK_STATE_INIT(&input_pos); - IOV_BLOCK_STATE_INIT(&output_pos); - krb5int_c_iov_get_block(iblock, BLOCK_SIZE, data, num_data, &input_pos); + k5_iov_cursor_init(&cursor, data, num_data, BLOCK_SIZE, FALSE); + k5_iov_cursor_get(&cursor, iblock); EVP_CIPHER_CTX_set_padding(&ciph_ctx,0); ret = EVP_EncryptUpdate(&ciph_ctx, oblock, &olen, iblock, BLOCK_SIZE); - if (ret == 1) { - krb5int_c_iov_put_block(data, num_data, oblock, BLOCK_SIZE, - &output_pos); - } + if (ret == 1) + k5_iov_cursor_put(&cursor, oblock); EVP_CIPHER_CTX_cleanup(&ciph_ctx); zap(iblock, BLOCK_SIZE); @@ -98,7 +95,7 @@ cbc_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, int ret = 0, olen = BLOCK_SIZE; unsigned char iblock[BLOCK_SIZE], oblock[BLOCK_SIZE]; EVP_CIPHER_CTX ciph_ctx; - struct iov_block_state input_pos, output_pos; + struct iov_cursor cursor; EVP_CIPHER_CTX_init(&ciph_ctx); ret = EVP_DecryptInit_ex(&ciph_ctx, map_mode(key->keyblock.length), @@ -106,15 +103,12 @@ cbc_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, if (ret == 0) return KRB5_CRYPTO_INTERNAL; - IOV_BLOCK_STATE_INIT(&input_pos); - IOV_BLOCK_STATE_INIT(&output_pos); - krb5int_c_iov_get_block(iblock, BLOCK_SIZE, data, num_data, &input_pos); + k5_iov_cursor_init(&cursor, data, num_data, BLOCK_SIZE, FALSE); + k5_iov_cursor_get(&cursor, iblock); EVP_CIPHER_CTX_set_padding(&ciph_ctx,0); ret = EVP_DecryptUpdate(&ciph_ctx, oblock, &olen, iblock, BLOCK_SIZE); - if (ret == 1) { - krb5int_c_iov_put_block(data, num_data, oblock, BLOCK_SIZE, - &output_pos); - } + if (ret == 1) + k5_iov_cursor_put(&cursor, oblock); EVP_CIPHER_CTX_cleanup(&ciph_ctx); zap(iblock, BLOCK_SIZE); @@ -130,7 +124,7 @@ cts_encr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t size = 0; unsigned char *oblock = NULL, *dbuf = NULL; unsigned char iv_cts[IV_CTS_BUF_SIZE]; - struct iov_block_state input_pos, output_pos; + struct iov_cursor cursor; AES_KEY enck; memset(iv_cts,0,sizeof(iv_cts)); @@ -150,22 +144,18 @@ cts_encr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, return ENOMEM; } - IOV_BLOCK_STATE_INIT(&input_pos); - IOV_BLOCK_STATE_INIT(&output_pos); - - krb5int_c_iov_get_block(dbuf, dlen, data, num_data, &input_pos); + k5_iov_cursor_init(&cursor, data, num_data, dlen, FALSE); + k5_iov_cursor_get(&cursor, dbuf); AES_set_encrypt_key(key->keyblock.contents, NUM_BITS * key->keyblock.length, &enck); size = CRYPTO_cts128_encrypt((unsigned char *)dbuf, oblock, dlen, &enck, iv_cts, (cbc128_f)AES_cbc_encrypt); - if (size <= 0) { + if (size <= 0) ret = KRB5_CRYPTO_INTERNAL; - } else { - krb5int_c_iov_put_block(data, num_data, - oblock, dlen, &output_pos); - } + else + k5_iov_cursor_put(&cursor, oblock); if (!ret && ivec && ivec->data) memcpy(ivec->data, iv_cts, sizeof(iv_cts)); @@ -187,7 +177,7 @@ cts_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, unsigned char *oblock = NULL; unsigned char *dbuf = NULL; unsigned char iv_cts[IV_CTS_BUF_SIZE]; - struct iov_block_state input_pos, output_pos; + struct iov_cursor cursor; AES_KEY deck; memset(iv_cts,0,sizeof(iv_cts)); @@ -197,9 +187,6 @@ cts_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, memcpy(iv_cts, ivec->data,ivec->length); } - IOV_BLOCK_STATE_INIT(&input_pos); - IOV_BLOCK_STATE_INIT(&output_pos); - oblock = OPENSSL_malloc(dlen); if (!oblock) return ENOMEM; @@ -212,16 +199,16 @@ cts_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, AES_set_decrypt_key(key->keyblock.contents, NUM_BITS * key->keyblock.length, &deck); - krb5int_c_iov_get_block(dbuf, dlen, data, num_data, &input_pos); + k5_iov_cursor_init(&cursor, data, num_data, dlen, FALSE); + k5_iov_cursor_get(&cursor, dbuf); size = CRYPTO_cts128_decrypt((unsigned char *)dbuf, oblock, dlen, &deck, iv_cts, (cbc128_f)AES_cbc_encrypt); if (size <= 0) ret = KRB5_CRYPTO_INTERNAL; - else { - krb5int_c_iov_put_block(data, num_data, oblock, dlen, &output_pos); - } + else + k5_iov_cursor_put(&cursor, oblock); if (!ret && ivec && ivec->data) memcpy(ivec->data, iv_cts, sizeof(iv_cts)); @@ -239,16 +226,9 @@ krb5int_aes_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { int ret = 0; - int nblocks = 0; - size_t input_length, i; - - 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; - } + size_t input_length, nblocks; + input_length = iov_total_length(data, num_data, FALSE); nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE; if (nblocks == 1) { if (input_length != BLOCK_SIZE) @@ -266,16 +246,9 @@ krb5int_aes_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { int ret = 0; - int nblocks = 0; - size_t input_length, i; - - 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; - } + size_t input_length, nblocks; + input_length = iov_total_length(data, num_data, FALSE); nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE; if (nblocks == 1) { if (input_length != BLOCK_SIZE) diff --git a/src/lib/crypto/openssl/enc_provider/camellia.c b/src/lib/crypto/openssl/enc_provider/camellia.c index 2173db6a86..3ac3fd999b 100644 --- a/src/lib/crypto/openssl/enc_provider/camellia.c +++ b/src/lib/crypto/openssl/enc_provider/camellia.c @@ -90,7 +90,7 @@ cbc_enc(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, int ret, olen = BLOCK_SIZE; unsigned char iblock[BLOCK_SIZE], oblock[BLOCK_SIZE]; EVP_CIPHER_CTX ciph_ctx; - struct iov_block_state input_pos, output_pos; + struct iov_cursor cursor; EVP_CIPHER_CTX_init(&ciph_ctx); ret = EVP_EncryptInit_ex(&ciph_ctx, map_mode(key->keyblock.length), @@ -98,15 +98,12 @@ cbc_enc(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, if (ret == 0) return KRB5_CRYPTO_INTERNAL; - IOV_BLOCK_STATE_INIT(&input_pos); - IOV_BLOCK_STATE_INIT(&output_pos); - krb5int_c_iov_get_block(iblock, BLOCK_SIZE, data, num_data, &input_pos); + k5_iov_cursor_init(&cursor, data, num_data, BLOCK_SIZE, FALSE); + k5_iov_cursor_get(&cursor, iblock); EVP_CIPHER_CTX_set_padding(&ciph_ctx,0); ret = EVP_EncryptUpdate(&ciph_ctx, oblock, &olen, iblock, BLOCK_SIZE); - if (ret == 1) { - krb5int_c_iov_put_block(data, num_data, oblock, BLOCK_SIZE, - &output_pos); - } + if (ret == 1) + k5_iov_cursor_put(&cursor, oblock); EVP_CIPHER_CTX_cleanup(&ciph_ctx); zap(iblock, BLOCK_SIZE); @@ -122,7 +119,7 @@ cbc_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, int ret = 0, olen = BLOCK_SIZE; unsigned char iblock[BLOCK_SIZE], oblock[BLOCK_SIZE]; EVP_CIPHER_CTX ciph_ctx; - struct iov_block_state input_pos, output_pos; + struct iov_cursor cursor; EVP_CIPHER_CTX_init(&ciph_ctx); ret = EVP_DecryptInit_ex(&ciph_ctx, map_mode(key->keyblock.length), @@ -130,15 +127,12 @@ cbc_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, if (ret == 0) return KRB5_CRYPTO_INTERNAL; - IOV_BLOCK_STATE_INIT(&input_pos); - IOV_BLOCK_STATE_INIT(&output_pos); - krb5int_c_iov_get_block(iblock, BLOCK_SIZE, data, num_data, &input_pos); + k5_iov_cursor_init(&cursor, data, num_data, BLOCK_SIZE, FALSE); + k5_iov_cursor_get(&cursor, iblock); EVP_CIPHER_CTX_set_padding(&ciph_ctx,0); ret = EVP_DecryptUpdate(&ciph_ctx, oblock, &olen, iblock, BLOCK_SIZE); - if (ret == 1) { - krb5int_c_iov_put_block(data, num_data, oblock, BLOCK_SIZE, - &output_pos); - } + if (ret == 1) + k5_iov_cursor_put(&cursor, oblock); EVP_CIPHER_CTX_cleanup(&ciph_ctx); zap(iblock, BLOCK_SIZE); @@ -154,7 +148,7 @@ cts_encr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t size = 0; unsigned char *oblock = NULL, *dbuf = NULL; unsigned char iv_cts[IV_CTS_BUF_SIZE]; - struct iov_block_state input_pos, output_pos; + struct iov_cursor cursor; CAMELLIA_KEY enck; memset(iv_cts,0,sizeof(iv_cts)); @@ -174,22 +168,18 @@ cts_encr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, return ENOMEM; } - IOV_BLOCK_STATE_INIT(&input_pos); - IOV_BLOCK_STATE_INIT(&output_pos); - - krb5int_c_iov_get_block(dbuf, dlen, data, num_data, &input_pos); + k5_iov_cursor_init(&cursor, data, num_data, dlen, FALSE); + k5_iov_cursor_get(&cursor, dbuf); Camellia_set_key(key->keyblock.contents, NUM_BITS * key->keyblock.length, &enck); size = CRYPTO_cts128_encrypt((unsigned char *)dbuf, oblock, dlen, &enck, iv_cts, (cbc128_f)Camellia_cbc_encrypt); - if (size <= 0) { + if (size <= 0) ret = KRB5_CRYPTO_INTERNAL; - } else { - krb5int_c_iov_put_block(data, num_data, - oblock, dlen, &output_pos); - } + else + k5_iov_cursor_put(&cursor, oblock); if (!ret && ivec && ivec->data) memcpy(ivec->data, iv_cts, sizeof(iv_cts)); @@ -211,7 +201,7 @@ cts_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, unsigned char *oblock = NULL; unsigned char *dbuf = NULL; unsigned char iv_cts[IV_CTS_BUF_SIZE]; - struct iov_block_state input_pos, output_pos; + struct iov_cursor cursor; CAMELLIA_KEY deck; memset(iv_cts,0,sizeof(iv_cts)); @@ -221,9 +211,6 @@ cts_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, memcpy(iv_cts, ivec->data,ivec->length); } - IOV_BLOCK_STATE_INIT(&input_pos); - IOV_BLOCK_STATE_INIT(&output_pos); - oblock = OPENSSL_malloc(dlen); if (!oblock) return ENOMEM; @@ -236,16 +223,16 @@ cts_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, Camellia_set_key(key->keyblock.contents, NUM_BITS * key->keyblock.length, &deck); - krb5int_c_iov_get_block(dbuf, dlen, data, num_data, &input_pos); + k5_iov_cursor_init(&cursor, data, num_data, dlen, FALSE); + k5_iov_cursor_get(&cursor, dbuf); size = CRYPTO_cts128_decrypt((unsigned char *)dbuf, oblock, dlen, &deck, iv_cts, (cbc128_f)Camellia_cbc_encrypt); if (size <= 0) ret = KRB5_CRYPTO_INTERNAL; - else { - krb5int_c_iov_put_block(data, num_data, oblock, dlen, &output_pos); - } + else + k5_iov_cursor_put(&cursor, oblock); if (!ret && ivec && ivec->data) memcpy(ivec->data, iv_cts, sizeof(iv_cts)); @@ -263,16 +250,9 @@ krb5int_camellia_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { int ret = 0; - int nblocks = 0; - size_t input_length, i; - - 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; - } + size_t input_length, nblocks; + input_length = iov_total_length(data, num_data, FALSE); nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE; if (nblocks == 1) { if (input_length != BLOCK_SIZE) @@ -290,16 +270,9 @@ krb5int_camellia_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { int ret = 0; - int nblocks = 0; - size_t input_length, i; - - 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; - } + size_t input_length, nblocks; + input_length = iov_total_length(data, num_data, FALSE); nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE; if (nblocks == 1) { if (input_length != BLOCK_SIZE) @@ -318,8 +291,8 @@ krb5int_camellia_cbc_mac(krb5_key key, const krb5_crypto_iov *data, krb5_data *output) { CAMELLIA_KEY enck; - unsigned char blockY[CAMELLIA_BLOCK_SIZE]; - struct iov_block_state iov_state; + unsigned char blockY[CAMELLIA_BLOCK_SIZE], blockB[CAMELLIA_BLOCK_SIZE]; + struct iov_cursor cursor; if (output->length < CAMELLIA_BLOCK_SIZE) return KRB5_BAD_MSIZE; @@ -332,17 +305,9 @@ krb5int_camellia_cbc_mac(krb5_key key, const krb5_crypto_iov *data, else memset(blockY, 0, CAMELLIA_BLOCK_SIZE); - IOV_BLOCK_STATE_INIT(&iov_state); - - for (;;) { - unsigned char blockB[CAMELLIA_BLOCK_SIZE]; - - if (!krb5int_c_iov_get_block(blockB, CAMELLIA_BLOCK_SIZE, data, - num_data, &iov_state)) - break; - + k5_iov_cursor_init(&cursor, data, num_data, CAMELLIA_BLOCK_SIZE, FALSE); + while (k5_iov_cursor_get(&cursor, blockB)) { xorblock(blockB, blockY); - Camellia_ecb_encrypt(blockB, blockY, &enck, 1); } diff --git a/src/lib/crypto/openssl/enc_provider/des.c b/src/lib/crypto/openssl/enc_provider/des.c index 644e26633e..1db5ef0f41 100644 --- a/src/lib/crypto/openssl/enc_provider/des.c +++ b/src/lib/crypto/openssl/enc_provider/des.c @@ -62,13 +62,7 @@ static krb5_error_code validate(krb5_key key, const krb5_data *ivec, const krb5_crypto_iov *data, size_t num_data, krb5_boolean *empty) { - 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; - } + size_t input_length = iov_total_length(data, num_data, FALSE); if (key->keyblock.length != DES_KEY_SIZE) return(KRB5_BAD_KEYSIZE); @@ -87,13 +81,10 @@ k5_des_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, { int ret, olen = DES_BLOCK_SIZE; unsigned char iblock[DES_BLOCK_SIZE], oblock[DES_BLOCK_SIZE]; - struct iov_block_state input_pos, output_pos; + struct iov_cursor cursor; EVP_CIPHER_CTX ciph_ctx; krb5_boolean empty; - IOV_BLOCK_STATE_INIT(&input_pos); - IOV_BLOCK_STATE_INIT(&output_pos); - ret = validate(key, ivec, data, num_data, &empty); if (ret != 0 || empty) return ret; @@ -107,19 +98,13 @@ k5_des_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, EVP_CIPHER_CTX_set_padding(&ciph_ctx,0); - for (;;) { - - if (!krb5int_c_iov_get_block(iblock, DES_BLOCK_SIZE, data, - num_data, &input_pos)) - break; - + k5_iov_cursor_init(&cursor, data, num_data, DES_BLOCK_SIZE, FALSE); + while (k5_iov_cursor_get(&cursor, iblock)) { ret = EVP_EncryptUpdate(&ciph_ctx, oblock, &olen, (unsigned char *)iblock, DES_BLOCK_SIZE); if (!ret) break; - - krb5int_c_iov_put_block(data, num_data, oblock, DES_BLOCK_SIZE, - &output_pos); + k5_iov_cursor_put(&cursor, oblock); } if (ivec != NULL) @@ -141,13 +126,10 @@ k5_des_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, { int ret, olen = DES_BLOCK_SIZE; unsigned char iblock[DES_BLOCK_SIZE], oblock[DES_BLOCK_SIZE]; - struct iov_block_state input_pos, output_pos; + struct iov_cursor cursor; EVP_CIPHER_CTX ciph_ctx; krb5_boolean empty; - IOV_BLOCK_STATE_INIT(&input_pos); - IOV_BLOCK_STATE_INIT(&output_pos); - ret = validate(key, ivec, data, num_data, &empty); if (ret != 0 || empty) return ret; @@ -162,18 +144,13 @@ k5_des_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, EVP_CIPHER_CTX_set_padding(&ciph_ctx,0); - for (;;) { - - if (!krb5int_c_iov_get_block(iblock, DES_BLOCK_SIZE, - data, num_data, &input_pos)) - break; - + k5_iov_cursor_init(&cursor, data, num_data, DES_BLOCK_SIZE, FALSE); + while (k5_iov_cursor_get(&cursor, iblock)) { ret = EVP_DecryptUpdate(&ciph_ctx, oblock, &olen, iblock, DES_BLOCK_SIZE); - if (!ret) break; - - krb5int_c_iov_put_block(data, num_data, oblock, - DES_BLOCK_SIZE, &output_pos); + if (!ret) + break; + k5_iov_cursor_put(&cursor, oblock); } if (ivec != NULL) @@ -194,7 +171,7 @@ k5_des_cbc_mac(krb5_key key, const krb5_crypto_iov *data, size_t num_data, const krb5_data *ivec, krb5_data *output) { int ret; - struct iov_block_state iov_state; + struct iov_cursor cursor; DES_cblock blockY, blockB; DES_key_schedule sched; krb5_boolean empty; @@ -214,11 +191,8 @@ k5_des_cbc_mac(krb5_key key, const krb5_crypto_iov *data, size_t num_data, else memset(blockY, 0, DES_BLOCK_SIZE); - IOV_BLOCK_STATE_INIT(&iov_state); - for (;;) { - if (!krb5int_c_iov_get_block(blockB, DES_BLOCK_SIZE, data, num_data, - &iov_state)) - break; + k5_iov_cursor_init(&cursor, data, num_data, DES_BLOCK_SIZE, FALSE); + while (k5_iov_cursor_get(&cursor, blockB)) { store_64_n(load_64_n(blockB) ^ load_64_n(blockY), blockB); DES_ecb_encrypt(&blockB, &blockY, &sched, 1); } diff --git a/src/lib/crypto/openssl/enc_provider/des3.c b/src/lib/crypto/openssl/enc_provider/des3.c index ca843f9f5e..d531f1036c 100644 --- a/src/lib/crypto/openssl/enc_provider/des3.c +++ b/src/lib/crypto/openssl/enc_provider/des3.c @@ -61,13 +61,7 @@ static krb5_error_code validate(krb5_key key, const krb5_data *ivec, const krb5_crypto_iov *data, size_t num_data, krb5_boolean *empty) { - 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; - } + size_t input_length = iov_total_length(data, num_data, FALSE); if (key->keyblock.length != DES3_KEY_SIZE) return(KRB5_BAD_KEYSIZE); @@ -86,7 +80,7 @@ k5_des3_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, { int ret, olen = DES3_BLOCK_SIZE; unsigned char iblock[DES3_BLOCK_SIZE], oblock[DES3_BLOCK_SIZE]; - struct iov_block_state input_pos, output_pos; + struct iov_cursor cursor; EVP_CIPHER_CTX ciph_ctx; krb5_boolean empty; @@ -94,9 +88,6 @@ k5_des3_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, if (ret != 0 || empty) return ret; - IOV_BLOCK_STATE_INIT(&input_pos); - IOV_BLOCK_STATE_INIT(&output_pos); - EVP_CIPHER_CTX_init(&ciph_ctx); ret = EVP_EncryptInit_ex(&ciph_ctx, EVP_des_ede3_cbc(), NULL, @@ -107,19 +98,13 @@ k5_des3_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, EVP_CIPHER_CTX_set_padding(&ciph_ctx,0); - for (;;) { - - if (!krb5int_c_iov_get_block(iblock, DES3_BLOCK_SIZE, - data, num_data, &input_pos)) - break; - + k5_iov_cursor_init(&cursor, data, num_data, DES3_BLOCK_SIZE, FALSE); + while (k5_iov_cursor_get(&cursor, iblock)) { ret = EVP_EncryptUpdate(&ciph_ctx, oblock, &olen, (unsigned char *)iblock, DES3_BLOCK_SIZE); if (!ret) break; - - krb5int_c_iov_put_block(data, num_data, - oblock, DES3_BLOCK_SIZE, &output_pos); + k5_iov_cursor_put(&cursor, oblock); } if (ivec != NULL) @@ -141,7 +126,7 @@ k5_des3_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, { int ret, olen = DES3_BLOCK_SIZE; unsigned char iblock[DES3_BLOCK_SIZE], oblock[DES3_BLOCK_SIZE]; - struct iov_block_state input_pos, output_pos; + struct iov_cursor cursor; EVP_CIPHER_CTX ciph_ctx; krb5_boolean empty; @@ -149,9 +134,6 @@ k5_des3_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, if (ret != 0 || empty) return ret; - IOV_BLOCK_STATE_INIT(&input_pos); - IOV_BLOCK_STATE_INIT(&output_pos); - EVP_CIPHER_CTX_init(&ciph_ctx); ret = EVP_DecryptInit_ex(&ciph_ctx, EVP_des_ede3_cbc(), NULL, @@ -162,19 +144,13 @@ k5_des3_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, EVP_CIPHER_CTX_set_padding(&ciph_ctx,0); - for (;;) { - - if (!krb5int_c_iov_get_block(iblock, DES3_BLOCK_SIZE, - data, num_data, &input_pos)) - break; - + k5_iov_cursor_init(&cursor, data, num_data, DES3_BLOCK_SIZE, FALSE); + while (k5_iov_cursor_get(&cursor, iblock)) { ret = EVP_DecryptUpdate(&ciph_ctx, oblock, &olen, (unsigned char *)iblock, DES3_BLOCK_SIZE); if (!ret) break; - - krb5int_c_iov_put_block(data, num_data, oblock, DES3_BLOCK_SIZE, - &output_pos); + k5_iov_cursor_put(&cursor, oblock); } if (ivec != NULL) |