Crypto IOV/non-IOV code consolidation
ghudson@MIT.EDU
ghudson at MIT.EDU
Tue Nov 17 15:51:09 EST 2009
There is a lot of code duplication in libk5crypto right now for three
reasons:
1. The IOV code was added in in parallel to the existing code,
duplicating much of the non-IOV code.
2. The AES derived-key code was added in in parallel to the existing
DES3 derived-key key, duplicating much of it. (Only for the
normal path, though; the IOV implementation factors out the
differing code.)
3. Encryption and decryption code commonly does a lot of the same
derived-key logic. I don't plan to do anything about that at
this time, but it does add another factor of two.
As a result, you can run across the same bit of logic as many as six
times while traversing the library.
The simplest starting point would be to take advantage of the existing
hatch in krb5_k_encrypt, which invokes krb5int_c_encrypt_aead_compat
if the enctype entry has no encrypt function (and likewise for
decryption). That would allow us to eliminate the non-IOV encryption
code.
Tom has expressed concerns about the extra copying in the aead_compat
functions resulting from the IOV code assuming in-place encryption and
decryption. I am not certain whether these copies have a significant
impact on performance, but I believe we can eliminate the need for
them by using a unified internal interface which would look a bit
like:
krb5_error_code (*encrypt)(<pointers to providers>,
krb5_key key, krb5_keyusage keyusage,
krb5_data *ivec,
krb5_crypto_iov *input, krb5_crypto_iov *output,
size_t num_data);
(And similarly for decrypt.) The IOV interfaces would pass the same
iov pointer for input and output. The non-IOV interfaces would
construct separate fixed-length iovs for input and output.
I'm hoping to find time to do this bit of code reorg. Some notes:
* The input and output iov structures aren't intrinsically parallel;
the ciphertext contains a header, padding, and trailer while the
plaintext is only data. At this point I don't know whether the
non-IOV APIs will construct plaintext IOV structures containing
dummy header/padding/trailer entries so that the input and output
have a 1:1 correspondence.
* krb5int_c_iov_{get,put}_block (internal functions used by the
enc_provider implementations) will need some massaging.
* I'd like to eliminate the aead_provider structure at the same time,
since it is confusing to have provider structures at two different
levels of abstraction. Since krb5int_dk_encrypt_iov needs to be
polymorphic in which crypto_length function it calls, the enctype
encrypt/decrypt functions will probably just receive a pointer to
the enctype entry instead of the enc/hash/aead providers, and the
crypto_length function will move from aead_provider to the enctype
table.
* Another bit of grossness is that gss-krb5 calls into krb5int_hmac,
passing a pointer to the RC4 enc_provider and the MD5 hash_provider.
(All three symbols are obtained via krb5int_accessor.) I need to
take a good hard look at that to see whether it can be cleaned up.
At a minimum it will need to be adjusted since the non-IOV functions
it relies on will be going away.
More information about the krbdev
mailing list