From: Andy Polyakov Date: Fri, 12 Feb 2016 13:07:27 +0000 (+0100) Subject: modes/ctr128.c: pay attention to ecount_buf alignment in CRYPTO_ctr128_encrypt. X-Git-Tag: OpenSSL_1_1_0-pre3~54 X-Git-Url: https://git.openssl.org/?p=openssl.git;a=commitdiff_plain;h=5e4bbeb49fb6522d858703201b5adee9611e7b7b modes/ctr128.c: pay attention to ecount_buf alignment in CRYPTO_ctr128_encrypt. It's never problem if CRYPTO_ctr128_encrypt is called from EVP, because buffer in question is always aligned within EVP_CIPHER_CTX structure. RT#4218 Reviewed-by: Richard Levitte --- diff --git a/crypto/modes/ctr128.c b/crypto/modes/ctr128.c index f56fd0cfad..4397494efb 100644 --- a/crypto/modes/ctr128.c +++ b/crypto/modes/ctr128.c @@ -67,23 +67,20 @@ /* increment counter (128-bit int) by 1 */ static void ctr128_inc(unsigned char *counter) { - u32 n = 16; - u8 c; + u32 n = 16, c = 1; do { --n; - c = counter[n]; - ++c; - counter[n] = c; - if (c) - return; + c += counter[n]; + counter[n] = (u8)c; + c >>= 8; } while (n); } #if !defined(OPENSSL_SMALL_FOOTPRINT) static void ctr128_inc_aligned(unsigned char *counter) { - size_t *data, c, n; + size_t *data, c, d, n; const union { long one; char little; @@ -91,20 +88,19 @@ static void ctr128_inc_aligned(unsigned char *counter) 1 }; - if (is_endian.little) { + if (is_endian.little || ((size_t)counter % sizeof(size_t)) != 0) { ctr128_inc(counter); return; } data = (size_t *)counter; + c = 1; n = 16 / sizeof(size_t); do { --n; - c = data[n]; - ++c; - data[n] = c; - if (c) - return; + d = data[n] += c; + /* did addition carry? */ + c = ((d - c) ^ d) >> (sizeof(size_t) * 8 - 1); } while (n); } #endif @@ -144,14 +140,14 @@ void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out, } # if defined(STRICT_ALIGNMENT) - if (((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != - 0) + if (((size_t)in | (size_t)out | (size_t)ecount_buf) + % sizeof(size_t) != 0) break; # endif while (len >= 16) { (*block) (ivec, ecount_buf, key); ctr128_inc_aligned(ivec); - for (; n < 16; n += sizeof(size_t)) + for (n = 0; n < 16; n += sizeof(size_t)) *(size_t *)(out + n) = *(size_t *)(in + n) ^ *(size_t *)(ecount_buf + n); len -= 16; @@ -189,16 +185,13 @@ void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out, /* increment upper 96 bits of 128-bit counter by 1 */ static void ctr96_inc(unsigned char *counter) { - u32 n = 12; - u8 c; + u32 n = 12, c = 1; do { --n; - c = counter[n]; - ++c; - counter[n] = c; - if (c) - return; + c += counter[n]; + counter[n] = (u8)c; + c >>= 8; } while (n); }