The struct krb5_context_data field can be passed to plugins
which might not be aware of the new structure layout. To
reduce the risk of data corruption, fields must never be
removed, modified or reordered. Old unused fields are marked
deprecated and new fields are appended to the end of the structure.
This change moves two fields that were added to master which
are not present in Heimdal 7.x:
fe43be8558 added config_include_depth.
5b39bd7c1d added no_ticket_store.
Change-Id: I28b157e128732324972c99b246a93a828bc077c1
Some versions of gcc can't follow the logic in the encryption path
of the _krb5_evp_encrypt_iov_cts code, and believe that it is
possible for the lastpos structure to be used uninitialised.
This isn't actually possible. On entry to the loop, remaining is
guaranteed to be both greater than, and a multiple of blocksize.
In order to exit the loop, remaining must be set to 0. If
cursor.current.length >= remaining, then we set remaining to 0 and
also set lastpos. Otherwise, we calculate the number of whole blocks
in the current iovec, which must be less than remaining, and subtract
that from remaining. Remaining must still be a multiple of and greater
than or equal to blocksize. If remaining == blocksize, we set lastpos,
and set remaining to 0. Otherwise we consume a single block, and go
around again. All of the paths which may set remaining to 0 also
set lastpos, so lastpos must be populated when the loop terminates.
Coverity has a similiar misconception, albeit with ivec2, which is
mistaken for the same reasons.
When we have an underlying iovec encryption function, use iovecs for
checksum-then-encrypt alogrithms in decrypt_iov_ivec, rather than
coalescing iovecs into a single memory buffer.
Add a verify operation for this checksum. If a verify operation isn't
defined, then the verify_checksum code has to dynamically allocate and
free a block of memory for the computed checksum, which can be a
significant overhead when performing bulk data encryption.
Add iovec routines for both padded CBC, and CTS EVP based encryption.
These routines go to great lengths to minimise the number of times
we call EVP_Cipher. With some EVP implementations (such as OpenSSL's
AES-NI) there is a significant entrance and exit overhead from this
routine, due to the use of SIMD vectors for the ivec.
Add a encrypt_iov function pointer to all of our encryption types
which can be used to implement an iovec based encryption routine.
Modify krb5_encrypt_iov so that it calls the iovec based routine
if it is available.
Use the iovec checksum routines in krb5_encrypt_iov_ivec. This
still marshalls all of the iovecs together to perform the encryption
operation, but this change halves the amount of time spent on
data marshalling in this function.
When we decide we need to zero the padding iovec, do so with 0, not
with the length that we've determined.
This had no effect because we zero the padding properly later, but it
should be fixed, so that things still work when the later memset() goes
away.
So that we can eventually use iovec hashes with encrypt, as well
as sign operations, add CRYPTO_TYPE_HEADER and CRYPTO_TYPE_PADDING
to the list of iovecs which will be hashed.
Creating and destroying an EVP_CTX_MD structure with every hash
operation is very expensive. Speed things up by caching one within
the krb5_crypto structure. krb5_crypto can already only be safely
used by one thread at a time - adding a message digest context here
shouldn't introduce any further threading risks.
Users of the stashed context must be careful to ensure that they
call no other hash functions whilst they are in the middle of using
the context.
Instead of flattening the iovecs passed into
krb5_verify_checksum_iov, create a new internal verify_checksum_iov
function which passes iovecs down onto the individual ->verify or
->checksum functions.
_krb5_find_enctype is a moderately expensive operation, as it
does a linear search of the enctype lists. Avoid calling it
in _key_schedule when we already have a key schedule in place.
This change makes the most common check the first in the function.
Rather than flattening the iovecs supplied to
krb5_create_checksum_iov into a malloc()'d memory block, refactor
the function so that they can be passed straight through to the
backend hash functions.
Modify the signature of the checksum operation in the
krb5_checksum_type structure so that it processes iovecs rather than
solid blocks of data.
Update all of the implementations of these functions for all of the
checksum types that we support so that they process iovecs, either
by iterating through the iovec in each function, or by calling
_krb5_evp_digest_iov or _krb5_evp_hmac_iov()
Update callers of these functions so that they turn their single blocks
of data into a single iovec of the correct type before calling checksum
Add a function which will perform an HMAC over a set of iovecs,
using the hcrypto provided HMAC functions.
Join contiguous iovecs together before passing them to the hash
function so we make as few calls into the hash as possible.
Add a pair of functions which can be used to allocate and free
an HMAC_CTX structure on the heap. This means that the caller doesn't
need to know the size of the underlying structure.
When replying to a door call, if allocating the buffer using malloc()
fails, we return EAGAIN to the client to avoid it hanging, using a
variable on the stack. However in this case the code did not reset the
reply length, which would result in it reading past the end of the stack.
At the expense of a goto, this patch uses the same path for returning an
error as if it was generating by the application.
Also, ensure that reply->length is set to zero when returning an error;
it shouldn't affect the client as it will not read this in the event of
a non-zero return code, but it avoids leaking uninitialized memory.
The ucred_t argument must be initialized to zero otherwise it is assumed to
point to allocated memory. Also, the logic is inverted: getpeerucred()
returns zero on success, not failure.
In the interest of being paranoid, when a WinCNG crypto or digest
context is being reinitialized, zero out the backing store as well
as destroying the handle.
This is required as the PKCS#11 library needs to be reinitialized after
forking. This was causing a problem with ipropd.
This fix appears to incur a repeatable 10ms performance penalty on aes-test.
Caching the initialization status using a once control and invalidating it
on fork provided no measurable performance benefit on Solaris 11. Other
approaches would not be thread-safe or would involve more intrusive code
changes, such as exposing heimbase's atomics.
Similar fix to a88d0066, but for the WinCNG EVP backend. However this
is just a fix for leaking handles if the same EVP context is used with
a new key; there is no functionality issue as cipherstate is maintained
directly in the EVP context, not internally by WinCNG.
Clients of the EVP API can reinitialize message digest contexts
without destroying them. The PKCS#11 backend assumed they were
only used once, and was leaking session handles upon reinitialization.
This fix disposes of any existing PKCS#11 message digest context
in the initialization method.
Some callers of EVP_DigestUpdate (such as libntlm) pass NULL as the
data argument. PKCS#11 returns CKR_ARGUMENTS_BAD which may poison
the context. Pass an empty string to C_DigestUpdate work around this.
81c778e broke the PKCS#11 hcrypto backend broke for many cases as it did
not support cipherstate resetting. (Prior to 81c778e, which was to fix#194,
the PKCS#11 backend did not support cipherstate chaining across invocations.)
hcrypto backends that maintain cipherstate independently of the hcrypto
context IV field need to set EVP_CIPH_ALWAYS_CALL_INIT to avoid the two
diverging. Their init function should support resetting the cipherstate
independently of key scheduling.
Solaris make won't allow @echo in a shell command string as there is no
command called @echo, and it passes the whole shell command to the shell
without poaching off the @ itself first