summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam Hartman <hartmans@mit.edu>2008-12-04 15:48:08 +0000
committerSam Hartman <hartmans@mit.edu>2008-12-04 15:48:08 +0000
commit9ab3afbf9569254cf67bf7363cb9a50f549a5cdf (patch)
tree6bccf2672cf7b33a77ed39d21287a0cd3deca33a
parent7a64640413a306635ad94403b72d798e4aa527ee (diff)
downloadkrb5-9ab3afbf9569254cf67bf7363cb9a50f549a5cdf.tar.gz
krb5-9ab3afbf9569254cf67bf7363cb9a50f549a5cdf.tar.xz
krb5-9ab3afbf9569254cf67bf7363cb9a50f549a5cdf.zip
Merge r21120 from mskrb-integ
Refactor code such that an AEAD provider does not need to implement the older, non-IOV SPIs. Instead, the older APIs will implement their behaviour on top of the AEAD SPIs, using the wrapper functions in aead.c. ticket: 6274 Status: open git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@21278 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r--src/lib/crypto/aead.c145
-rw-r--r--src/lib/crypto/aead.h40
-rw-r--r--src/lib/crypto/crypto_length.c26
-rw-r--r--src/lib/crypto/decrypt.c11
-rw-r--r--src/lib/crypto/encrypt.c11
-rw-r--r--src/lib/crypto/encrypt_length.c16
6 files changed, 210 insertions, 39 deletions
diff --git a/src/lib/crypto/aead.c b/src/lib/crypto/aead.c
index 6d042e60d..547aee861 100644
--- a/src/lib/crypto/aead.c
+++ b/src/lib/crypto/aead.c
@@ -30,7 +30,7 @@
#include "dk.h"
#include "aead.h"
-krb5_crypto_iov * KRB5_CALLCONV
+krb5_crypto_iov *
krb5int_c_locate_iov(krb5_crypto_iov *data,
size_t num_data,
krb5_cryptotype type)
@@ -91,7 +91,7 @@ make_unkeyed_checksum_iov(const struct krb5_hash_provider *hash_provider,
return ret;
}
-krb5_error_code KRB5_CALLCONV
+krb5_error_code
krb5int_c_make_checksum_iov(const struct krb5_cksumtypes *cksum_type,
const krb5_keyblock *key,
krb5_keyusage usage,
@@ -152,7 +152,7 @@ cleanup:
return ret;
}
-const struct krb5_cksumtypes * KRB5_CALLCONV
+const struct krb5_cksumtypes *
krb5int_c_find_checksum_type(krb5_cksumtype cksumtype)
{
size_t i;
@@ -243,7 +243,7 @@ pad_to_boundary_p(const krb5_crypto_iov *data,
return 1;
}
-krb5_boolean KRB5_CALLCONV
+krb5_boolean
krb5int_c_iov_get_block(unsigned char *block,
size_t block_size,
const krb5_crypto_iov *data,
@@ -296,7 +296,7 @@ krb5int_c_iov_get_block(unsigned char *block,
return (iov_state->iov_pos < num_data);
}
-krb5_boolean KRB5_CALLCONV
+krb5_boolean
krb5int_c_iov_put_block(const krb5_crypto_iov *data,
size_t num_data,
unsigned char *block,
@@ -346,7 +346,7 @@ krb5int_c_iov_put_block(const krb5_crypto_iov *data,
return (iov_state->iov_pos < num_data);
}
-krb5_error_code KRB5_CALLCONV
+krb5_error_code
krb5int_c_iov_decrypt_stream(const struct krb5_aead_provider *aead,
const struct krb5_enc_provider *enc,
const struct krb5_hash_provider *hash,
@@ -429,3 +429,136 @@ krb5int_c_iov_decrypt_stream(const struct krb5_aead_provider *aead,
return ret;
}
+krb5_error_code
+krb5int_padding_length(const struct krb5_aead_provider *aead,
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ size_t data_length,
+ unsigned int *pad_length)
+{
+ unsigned int padding;
+ krb5_error_code ret;
+
+ ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_PADDING, &padding);
+ if (ret != 0)
+ return ret;
+
+ if (padding == 0 || (data_length % padding) == 0)
+ *pad_length = 0;
+ else
+ *pad_length = padding - (data_length % padding);
+
+ return 0;
+}
+
+krb5_error_code
+krb5int_encrypt_aead_compat(const struct krb5_aead_provider *aead,
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ const krb5_keyblock *key, krb5_keyusage usage,
+ const krb5_data *ivec, const krb5_data *input,
+ krb5_data *output)
+{
+ krb5_crypto_iov iov[4];
+ krb5_error_code ret;
+ size_t header_len = 0;
+ size_t padding_len = 0;
+ size_t trailer_len = 0;
+
+ ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_HEADER,
+ &header_len);
+ if (ret != 0)
+ return ret;
+
+ ret = krb5int_padding_length(aead, enc, hash, input->length, &padding_len);
+ if (ret != 0)
+ return ret;
+
+ ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_TRAILER,
+ &trailer_len);
+ if (ret != 0)
+ return ret;
+
+ if (output->length < header_len + input->length + padding_len + trailer_len)
+ return KRB5_BAD_MSIZE;
+
+ iov[0].flags = KRB5_CRYPTO_TYPE_HEADER;
+ iov[0].data.data = output->data;
+ iov[0].data.length = header_len;
+
+ iov[1].flags = KRB5_CRYPTO_TYPE_DATA;
+ iov[1].data.data = iov[0].data.data + iov[0].data.length;
+ iov[1].data.length = input->length;
+ memcpy(iov[1].data.data, input->data, input->length);
+
+ iov[2].flags = KRB5_CRYPTO_TYPE_PADDING;
+ iov[2].data.data = iov[1].data.data + iov[1].data.length;
+ iov[2].data.length = padding_len;
+
+ iov[3].flags = KRB5_CRYPTO_TYPE_TRAILER;
+ iov[3].data.data = iov[2].data.data + iov[2].data.length;
+ iov[3].data.length = trailer_len;
+
+ ret = aead->encrypt_iov(aead, enc, hash, key,
+ usage, ivec,
+ iov, sizeof(iov)/sizeof(iov[0]));
+
+ if (ret != 0)
+ zap(iov[1].data.data, iov[1].data.length);
+
+ output->length = iov[0].data.length + iov[1].data.length +
+ iov[2].data.length + iov[3].data.length;
+
+ return ret;
+}
+
+krb5_error_code
+krb5int_decrypt_aead_compat(const struct krb5_aead_provider *aead,
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ const krb5_keyblock *key, krb5_keyusage usage,
+ const krb5_data *ivec, const krb5_data *input,
+ krb5_data *output)
+{
+ krb5_crypto_iov iov[2];
+ krb5_error_code ret;
+
+ iov[0].flags = KRB5_CRYPTO_TYPE_STREAM;
+ iov[0].data = *input;
+
+ iov[1].flags = KRB5_CRYPTO_TYPE_DATA;
+ iov[1].data.data = NULL;
+ iov[1].data.length = 0;
+
+ ret = krb5int_c_iov_decrypt_stream(aead, enc, hash, key,
+ usage, ivec,
+ iov, sizeof(iov)/sizeof(iov[0]));
+ if (ret != 0)
+ return ret;
+
+ if (output->length < iov[1].data.length)
+ return KRB5_BAD_MSIZE;
+
+ memcpy(output->data, iov[1].data.data, iov[1].data.length);
+ output->length = iov[1].data.length;
+
+ return ret;
+}
+
+void
+krb5int_encrypt_length_aead_compat(const struct krb5_aead_provider *aead,
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ size_t inputlen, size_t *length)
+{
+ size_t header_len = 0;
+ size_t padding_len = 0;
+ size_t trailer_len = 0;
+
+ aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_HEADER, &header_len);
+ krb5int_padding_length(aead, enc, hash, inputlen, &padding_len);
+ aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_TRAILER, &trailer_len);
+
+ *length = header_len + inputlen + padding_len + trailer_len;
+}
+
diff --git a/src/lib/crypto/aead.h b/src/lib/crypto/aead.h
index f183d1a05..057d6a7d4 100644
--- a/src/lib/crypto/aead.h
+++ b/src/lib/crypto/aead.h
@@ -28,12 +28,12 @@
/* AEAD helpers */
-krb5_crypto_iov * KRB5_CALLCONV
+krb5_crypto_iov *
krb5int_c_locate_iov(krb5_crypto_iov *data,
size_t num_data,
krb5_cryptotype type);
-krb5_error_code KRB5_CALLCONV
+krb5_error_code
krb5int_c_make_checksum_iov(const struct krb5_cksumtypes *cksum,
const krb5_keyblock *key,
krb5_keyusage usage,
@@ -41,7 +41,7 @@ krb5int_c_make_checksum_iov(const struct krb5_cksumtypes *cksum,
size_t num_data,
krb5_data *cksum_data);
-const struct krb5_cksumtypes * KRB5_CALLCONV
+const struct krb5_cksumtypes *
krb5int_c_find_checksum_type(krb5_cksumtype cksumtype);
#define ENCRYPT_CONF_IOV(_iov) ((_iov)->flags == KRB5_CRYPTO_TYPE_HEADER)
@@ -68,21 +68,21 @@ struct iov_block_state {
(_state)->include_sign_only = \
(_state)->pad_to_boundary = 0)
-krb5_boolean KRB5_CALLCONV
+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);
-krb5_boolean KRB5_CALLCONV
+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);
-krb5_error_code KRB5_CALLCONV
+krb5_error_code
krb5int_c_iov_decrypt_stream(const struct krb5_aead_provider *aead,
const struct krb5_enc_provider *enc,
const struct krb5_hash_provider *hash,
@@ -92,3 +92,31 @@ krb5int_c_iov_decrypt_stream(const struct krb5_aead_provider *aead,
krb5_crypto_iov *data,
size_t num_data);
+krb5_error_code
+krb5int_decrypt_aead_compat(const struct krb5_aead_provider *aead,
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ const krb5_keyblock *key, krb5_keyusage usage,
+ const krb5_data *ivec, const krb5_data *input,
+ krb5_data *output);
+
+krb5_error_code
+krb5int_encrypt_aead_compat(const struct krb5_aead_provider *aead,
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ const krb5_keyblock *key, krb5_keyusage usage,
+ const krb5_data *ivec, const krb5_data *input,
+ krb5_data *output);
+
+void
+krb5int_encrypt_length_aead_compat(const struct krb5_aead_provider *aead,
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ size_t inputlen, size_t *length);
+
+krb5_error_code
+krb5int_padding_length(const struct krb5_aead_provider *aead,
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ size_t data_length,
+ unsigned int *pad_length);
diff --git a/src/lib/crypto/crypto_length.c b/src/lib/crypto/crypto_length.c
index 4a64b90f9..eb19b5990 100644
--- a/src/lib/crypto/crypto_length.c
+++ b/src/lib/crypto/crypto_length.c
@@ -73,28 +73,6 @@ krb5_c_crypto_length(krb5_context context,
return ret;
}
-static krb5_error_code
-k5_padding_length(const struct krb5_keytypes *ktp,
- size_t data_length,
- unsigned int *pad_length)
-{
- unsigned int padding;
- krb5_error_code ret;
-
- ret = ktp->aead->crypto_length(ktp->aead, ktp->enc, ktp->hash,
- KRB5_CRYPTO_TYPE_PADDING, &padding);
- if (ret != 0)
- return ret;
-
- if (padding == 0 || (data_length % padding) == 0)
- *pad_length = 0;
- else
- *pad_length = padding - (data_length % padding);
-
- return 0;
-}
-
-
krb5_error_code KRB5_CALLCONV
krb5_c_padding_length(krb5_context context,
krb5_enctype enctype,
@@ -115,7 +93,7 @@ krb5_c_padding_length(krb5_context context,
return KRB5_BAD_ENCTYPE;
}
- return k5_padding_length(ktp, data_length, pad_length);
+ return krb5int_padding_length(ktp->aead, ktp->enc, ktp->hash, data_length, pad_length);
}
krb5_error_code KRB5_CALLCONV
@@ -177,7 +155,7 @@ krb5_c_crypto_length_iov(krb5_context context,
if (ret != 0)
return ret;
- ret = k5_padding_length(ktp, data_length, &pad_length);
+ ret = krb5int_padding_length(ktp->aead, ktp->enc, ktp->hash, data_length, &pad_length);
if (ret != 0)
return ret;
diff --git a/src/lib/crypto/decrypt.c b/src/lib/crypto/decrypt.c
index 96861bda1..3c33c83c1 100644
--- a/src/lib/crypto/decrypt.c
+++ b/src/lib/crypto/decrypt.c
@@ -26,6 +26,7 @@
#include "k5-int.h"
#include "etypes.h"
+#include "aead.h"
krb5_error_code KRB5_CALLCONV
krb5_c_decrypt(krb5_context context, const krb5_keyblock *key,
@@ -50,6 +51,16 @@ krb5_c_decrypt(krb5_context context, const krb5_keyblock *key,
(krb5_enctypes_list[i].etype != input->enctype))
return(KRB5_BAD_ENCTYPE);
+ if (krb5_enctypes_list[i].decrypt == NULL) {
+ assert(krb5_enctypes_list[i].aead != NULL);
+
+ return krb5int_decrypt_aead_compat(krb5_enctypes_list[i].aead,
+ krb5_enctypes_list[i].enc,
+ krb5_enctypes_list[i].hash,
+ key, usage, ivec,
+ &input->ciphertext, output);
+ }
+
return((*(krb5_enctypes_list[i].decrypt))
(krb5_enctypes_list[i].enc, krb5_enctypes_list[i].hash,
key, usage, ivec, &input->ciphertext, output));
diff --git a/src/lib/crypto/encrypt.c b/src/lib/crypto/encrypt.c
index c215dc429..414736675 100644
--- a/src/lib/crypto/encrypt.c
+++ b/src/lib/crypto/encrypt.c
@@ -26,6 +26,7 @@
#include "k5-int.h"
#include "etypes.h"
+#include "aead.h"
krb5_error_code KRB5_CALLCONV
krb5_c_encrypt(krb5_context context, const krb5_keyblock *key,
@@ -46,6 +47,16 @@ krb5_c_encrypt(krb5_context context, const krb5_keyblock *key,
output->kvno = 0;
output->enctype = key->enctype;
+ if (krb5_enctypes_list[i].encrypt == NULL) {
+ assert(krb5_enctypes_list[i].aead != NULL);
+
+ return krb5int_encrypt_aead_compat(krb5_enctypes_list[i].aead,
+ krb5_enctypes_list[i].enc,
+ krb5_enctypes_list[i].hash,
+ key, usage, ivec,
+ input, &output->ciphertext);
+ }
+
return((*(krb5_enctypes_list[i].encrypt))
(krb5_enctypes_list[i].enc, krb5_enctypes_list[i].hash,
key, usage, ivec, input, &output->ciphertext));
diff --git a/src/lib/crypto/encrypt_length.c b/src/lib/crypto/encrypt_length.c
index 71c25e735..fca1da248 100644
--- a/src/lib/crypto/encrypt_length.c
+++ b/src/lib/crypto/encrypt_length.c
@@ -26,6 +26,7 @@
#include "k5-int.h"
#include "etypes.h"
+#include "aead.h"
krb5_error_code KRB5_CALLCONV
krb5_c_encrypt_length(krb5_context context, krb5_enctype enctype,
@@ -41,9 +42,18 @@ krb5_c_encrypt_length(krb5_context context, krb5_enctype enctype,
if (i == krb5_enctypes_length)
return(KRB5_BAD_ENCTYPE);
- (*(krb5_enctypes_list[i].encrypt_len))
- (krb5_enctypes_list[i].enc, krb5_enctypes_list[i].hash,
- inputlen, length);
+ if (krb5_enctypes_list[i].encrypt_len == NULL) {
+ assert(krb5_enctypes_list[i].aead != NULL);
+
+ krb5int_encrypt_length_aead_compat(krb5_enctypes_list[i].aead,
+ krb5_enctypes_list[i].enc,
+ krb5_enctypes_list[i].hash,
+ inputlen, length);
+ } else {
+ (*(krb5_enctypes_list[i].encrypt_len))
+ (krb5_enctypes_list[i].enc, krb5_enctypes_list[i].hash,
+ inputlen, length);
+ }
return(0);
}