diff options
author | Sam Hartman <hartmans@mit.edu> | 2008-12-01 16:43:24 +0000 |
---|---|---|
committer | Sam Hartman <hartmans@mit.edu> | 2008-12-01 16:43:24 +0000 |
commit | 0f1220d9d961bbc03993f405349af0a569a8792a (patch) | |
tree | 7652ad187ad3c9187c1d20bee915da8622bbcc61 | |
parent | 79ba9dd1a6b99dd54c67abc7c4253c72cceb5b3b (diff) | |
download | krb5-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.c | 49 | ||||
-rw-r--r-- | src/lib/crypto/aead.h | 8 | ||||
-rw-r--r-- | src/lib/crypto/des/d3_aead.c | 30 |
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); } |