X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb/blobdiff_plain/0f00dc4c8eb47e67bc0f148c2dd109f73a451e0a..3b09bd841c6f31e968717e46b5e995fff0481924:/symm/des.c diff --git a/symm/des.c b/symm/des.c index 06400a15..19407bc8 100644 --- a/symm/des.c +++ b/symm/des.c @@ -100,6 +100,49 @@ static void permute(const char *p, uint32 a, uint32 b, uint32 *d) d[1] = y; } +/* --- @des_fixparity@ --- * + * + * Arguments: @octet *z@ = output buffer pointer, or null + * @const octet *p@ = input buffer pointer + * @size_t sz@ = size of the buffers + * + * Returns: Zero if the input already had correct parity, @-1@ if changes + * were necessary (in constant time). + * + * Use: Check the @sz@ bytes at @p@ for odd parity (as used in DES + * keys); if @z@ is not null, then copy a parity-fixed version + * of @p@ to @z@. The two buffers at @p@ and @z@ may coincide, + * or be disjoint, but not otherwise overlap. + */ + +int des_fixparity(octet *z, const octet *p, size_t sz) +{ + int a = 0, t, u; + + while (sz--) { + + /* Collect the byte. */ + t = *p++; + + /* Compute the parity. Specifically, this will determine the overall + * parity of the byte: 0 for odd, and 1 for even (since we complement + * the result). This is therefore the change which needs to be applied + * to the incoming byte to ensure that it has odd parity. + */ + u = t; u ^= u >> 4; u ^= u >> 2; u ^= u >> 1; u ^= 1; u &= 1; + + /* Accumulate the difference. If any bytes had even parity, then this + * will equal 1. */ + a |= u; + + /* Maybe write out the fixed value. */ + if (z) *z++ = t ^ u; + } + + /* Done. */ + return (-a); +} + /* --- @des_expand@ --- * * * Arguments: @const octet *k@ = pointer to key material