Merge r21120 from mskrb-integ
authorSam Hartman <hartmans@mit.edu>
Thu, 4 Dec 2008 15:48:08 +0000 (15:48 +0000)
committerSam Hartman <hartmans@mit.edu>
Thu, 4 Dec 2008 15:48:08 +0000 (15:48 +0000)
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

src/lib/crypto/aead.c
src/lib/crypto/aead.h
src/lib/crypto/crypto_length.c
src/lib/crypto/decrypt.c
src/lib/crypto/encrypt.c
src/lib/crypto/encrypt_length.c

index 6d042e60dad539882514a2c671d8478c4eca6ccf..547aee861aef185be7cb0f5a747b0a352ae3a9f1 100644 (file)
@@ -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;
+}
+
index f183d1a05b9243936d134074c2cabe366b8036e9..057d6a7d463e7da18bf77c103642844b0852b64e 100644 (file)
 
 /* 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);
index 4a64b90f913fb6aeb27bc21d46784e7c2c2f84dd..eb19b59905e40550bddd8652bed7e634912d39ff 100644 (file)
@@ -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;
 
index 96861bda16bf0ffe2ae907fddd49eea07b44a95e..3c33c83c10598ec95d2c670bac8c85a3ccc042f5 100644 (file)
@@ -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));
index c215dc42931a9e7a0cd1274daa09962465551966..4147366751ed2662f14d591f4ac9f9df70b7cd89 100644 (file)
@@ -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));
index 71c25e7353a8e767e65458e4973c98238c20a8bd..fca1da24892f298df72e888556e077c3df2e06b1 100644 (file)
@@ -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);
 }