Commit 5e4bbeb4 authored by Andy Polyakov's avatar Andy Polyakov
Browse files

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: default avatarRichard Levitte <levitte@openssl.org>
parent 3c65577f
Loading
Loading
Loading
Loading
+17 −24
Original line number Diff line number Diff line
@@ -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);
}