aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Hartman <hartmans@mit.edu>2008-12-01 16:43:24 +0000
committerSam Hartman <hartmans@mit.edu>2008-12-01 16:43:24 +0000
commit0f1220d9d961bbc03993f405349af0a569a8792a (patch)
tree7652ad187ad3c9187c1d20bee915da8622bbcc61
parent79ba9dd1a6b99dd54c67abc7c4253c72cceb5b3b (diff)
downloadkrb5-0f1220d9d961bbc03993f405349af0a569a8792a.zip
krb5-0f1220d9d961bbc03993f405349af0a569a8792a.tar.gz
krb5-0f1220d9d961bbc03993f405349af0a569a8792a.tar.bz2
Provisional implementation of CCM mode for AES
git-svn-id: svn://anonsvn.mit.edu/krb5/branches/mskrb-integ-crypto-iov@21235 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r--src/lib/crypto/aead.c49
-rw-r--r--src/lib/crypto/aead.h8
-rw-r--r--src/lib/crypto/des/d3_aead.c30
3 files changed, 67 insertions, 20 deletions
diff --git a/src/lib/crypto/aead.c b/src/lib/crypto/aead.c
index b539ab9..1757ed7 100644
--- a/src/lib/crypto/aead.c
+++ b/src/lib/crypto/aead.c
@@ -168,6 +168,47 @@ krb5int_c_find_checksum_type(krb5_cksumtype cksumtype)
return &krb5_cksumtypes_list[i];
}
+static 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_HEADER:
+ /* Because SIGN_ONLY headers share padding with SIGN_ONLY data */
+ process_block = iov_state->include_sign_only ? 1 : (iov_state->got_header == 0);
+ break;
+ case KRB5_CRYPTO_TYPE_PADDING: {
+ const krb5_crypto_iov *data_to_pad;
+
+ if (i > 0) {
+ data_to_pad = &data[i - 1];
+
+ if (data_to_pad->flags == KRB5_CRYPTO_TYPE_SIGN_ONLY)
+ process_block = iov_state->include_sign_only;
+ else if (data_to_pad->flags == KRB5_CRYPTO_TYPE_DATA)
+ process_block = 1;
+ }
+ break;
+ }
+ case KRB5_CRYPTO_TYPE_SIGN_ONLY:
+ process_block = iov_state->include_sign_only;
+ break;
+ case KRB5_CRYPTO_TYPE_DATA:
+ process_block = 1;
+ break;
+ default:
+ process_block = 0;
+ break;
+ }
+
+ return process_block;
+}
+
void KRB5_CALLCONV
krb5int_c_iov_get_block(unsigned char *block,
size_t block_size,
@@ -181,9 +222,7 @@ krb5int_c_iov_get_block(unsigned char *block,
const krb5_crypto_iov *iov = &data[i];
size_t nbytes;
- if (iov_state->got_header ?
- !ENCRYPT_DATA_IOV(iov) :
- !ENCRYPT_CONF_IOV(iov))
+ if (!process_block_p(data, num_data, iov_state, i))
continue;
nbytes = iov->data.length - iov_state->data_pos;
@@ -232,9 +271,7 @@ krb5int_c_iov_put_block(const krb5_crypto_iov *data,
const krb5_crypto_iov *iov = &data[i];
size_t nbytes;
- if (iov_state->got_header ?
- !ENCRYPT_DATA_IOV(iov) :
- !ENCRYPT_CONF_IOV(iov))
+ if (!process_block_p(data, num_data, iov_state, i))
continue;
nbytes = iov->data.length - iov_state->data_pos;
diff --git a/src/lib/crypto/aead.h b/src/lib/crypto/aead.h
index 9554ee0..9c1c49b 100644
--- a/src/lib/crypto/aead.h
+++ b/src/lib/crypto/aead.h
@@ -57,10 +57,14 @@ krb5int_c_find_checksum_type(krb5_cksumtype cksumtype);
struct iov_block_state {
size_t iov_pos;
size_t data_pos;
- krb5_boolean got_header;
+ unsigned int got_header : 1;
+ unsigned int include_sign_only : 1;
};
-#define IOV_BLOCK_STATE_INIT(_state) ((_state)->iov_pos = (_state)->data_pos = (_state)->got_header = 0)
+#define IOV_BLOCK_STATE_INIT(_state) ((_state)->iov_pos = \
+ (_state)->data_pos = \
+ (_state)->got_header = \
+ (_state)->include_sign_only = 0)
void KRB5_CALLCONV
krb5int_c_iov_get_block(unsigned char *block,
diff --git a/src/lib/crypto/des/d3_aead.c b/src/lib/crypto/des/d3_aead.c
index 2147046..9605bac 100644
--- a/src/lib/crypto/des/d3_aead.c
+++ b/src/lib/crypto/des/d3_aead.c
@@ -38,6 +38,8 @@ krb5int_des3_cbc_encrypt_iov(krb5_crypto_iov *data,
const unsigned char *ip;
unsigned char *op;
struct iov_block_state input_pos, output_pos;
+ unsigned char iblock[MIT_DES_BLOCK_LENGTH];
+ unsigned char oblock[MIT_DES_BLOCK_LENGTH];
IOV_BLOCK_STATE_INIT(&input_pos);
IOV_BLOCK_STATE_INIT(&output_pos);
@@ -64,16 +66,17 @@ krb5int_des3_cbc_encrypt_iov(krb5_crypto_iov *data,
* Suitably initialized, now work the length down 8 bytes
* at a time.
*/
- do {
+ for (;;) {
unsigned DES_INT32 temp;
- unsigned char iblock[MIT_DES_BLOCK_LENGTH];
- unsigned char oblock[MIT_DES_BLOCK_LENGTH];
ip = iblock;
op = oblock;
krb5int_c_iov_get_block(iblock, MIT_DES_BLOCK_LENGTH, data, num_data, &input_pos);
+ if (input_pos.iov_pos == num_data)
+ break;
+
GET_HALF_BLOCK(temp, ip);
left ^= temp;
GET_HALF_BLOCK(temp, ip);
@@ -93,10 +96,10 @@ krb5int_des3_cbc_encrypt_iov(krb5_crypto_iov *data,
PUT_HALF_BLOCK(right, op);
krb5int_c_iov_put_block(data, num_data, oblock, MIT_DES_BLOCK_LENGTH, &output_pos);
+ }
- if (input_pos.iov_pos == num_data && ivec != NULL)
- memcpy(ivec, oblock, MIT_DES_BLOCK_LENGTH);
- } while (input_pos.iov_pos != num_data);
+ if (ivec != NULL)
+ memcpy(ivec, oblock, MIT_DES_BLOCK_LENGTH);
}
void
@@ -114,6 +117,8 @@ krb5int_des3_cbc_decrypt_iov(krb5_crypto_iov *data,
unsigned DES_INT32 cipherl, cipherr;
unsigned char *op;
struct iov_block_state input_pos, output_pos;
+ unsigned char iblock[MIT_DES_BLOCK_LENGTH];
+ unsigned char oblock[MIT_DES_BLOCK_LENGTH];
IOV_BLOCK_STATE_INIT(&input_pos);
IOV_BLOCK_STATE_INIT(&output_pos);
@@ -147,16 +152,17 @@ krb5int_des3_cbc_decrypt_iov(krb5_crypto_iov *data,
/*
* Now do this in earnest until we run out of length.
*/
- do {
+ for (;;) {
/*
* Read a block from the input into left and
* right. Save this cipher block for later.
*/
- unsigned char iblock[MIT_DES_BLOCK_LENGTH];
- unsigned char oblock[MIT_DES_BLOCK_LENGTH];
krb5int_c_iov_get_block(iblock, MIT_DES_BLOCK_LENGTH, data, num_data, &input_pos);
+ if (input_pos.iov_pos == num_data)
+ break;
+
ip = iblock;
op = oblock;
@@ -189,8 +195,8 @@ krb5int_des3_cbc_decrypt_iov(krb5_crypto_iov *data,
ocipherr = cipherr;
krb5int_c_iov_put_block(data, num_data, oblock, MIT_DES_BLOCK_LENGTH, &output_pos);
+ }
- if (input_pos.iov_pos == num_data && ivec != NULL)
- memcpy(ivec, oblock, MIT_DES_BLOCK_LENGTH);
- } while (input_pos.iov_pos != num_data);
+ if (ivec != NULL)
+ memcpy(ivec, oblock, MIT_DES_BLOCK_LENGTH);
}