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 <levitte@openssl.org>
(cherry picked from commit 5e4bbeb49f
)
This commit is contained in:
parent
b4b23d05d3
commit
6533a0b8d1
1 changed files with 17 additions and 24 deletions
|
@ -67,23 +67,20 @@
|
||||||
/* increment counter (128-bit int) by 1 */
|
/* increment counter (128-bit int) by 1 */
|
||||||
static void ctr128_inc(unsigned char *counter)
|
static void ctr128_inc(unsigned char *counter)
|
||||||
{
|
{
|
||||||
u32 n = 16;
|
u32 n = 16, c = 1;
|
||||||
u8 c;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
--n;
|
--n;
|
||||||
c = counter[n];
|
c += counter[n];
|
||||||
++c;
|
counter[n] = (u8)c;
|
||||||
counter[n] = c;
|
c >>= 8;
|
||||||
if (c)
|
|
||||||
return;
|
|
||||||
} while (n);
|
} while (n);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(OPENSSL_SMALL_FOOTPRINT)
|
#if !defined(OPENSSL_SMALL_FOOTPRINT)
|
||||||
static void ctr128_inc_aligned(unsigned char *counter)
|
static void ctr128_inc_aligned(unsigned char *counter)
|
||||||
{
|
{
|
||||||
size_t *data, c, n;
|
size_t *data, c, d, n;
|
||||||
const union {
|
const union {
|
||||||
long one;
|
long one;
|
||||||
char little;
|
char little;
|
||||||
|
@ -91,20 +88,19 @@ static void ctr128_inc_aligned(unsigned char *counter)
|
||||||
1
|
1
|
||||||
};
|
};
|
||||||
|
|
||||||
if (is_endian.little) {
|
if (is_endian.little || ((size_t)counter % sizeof(size_t)) != 0) {
|
||||||
ctr128_inc(counter);
|
ctr128_inc(counter);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = (size_t *)counter;
|
data = (size_t *)counter;
|
||||||
|
c = 1;
|
||||||
n = 16 / sizeof(size_t);
|
n = 16 / sizeof(size_t);
|
||||||
do {
|
do {
|
||||||
--n;
|
--n;
|
||||||
c = data[n];
|
d = data[n] += c;
|
||||||
++c;
|
/* did addition carry? */
|
||||||
data[n] = c;
|
c = ((d - c) ^ d) >> (sizeof(size_t) * 8 - 1);
|
||||||
if (c)
|
|
||||||
return;
|
|
||||||
} while (n);
|
} while (n);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -144,14 +140,14 @@ void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out,
|
||||||
}
|
}
|
||||||
|
|
||||||
# if defined(STRICT_ALIGNMENT)
|
# if defined(STRICT_ALIGNMENT)
|
||||||
if (((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) !=
|
if (((size_t)in | (size_t)out | (size_t)ecount_buf)
|
||||||
0)
|
% sizeof(size_t) != 0)
|
||||||
break;
|
break;
|
||||||
# endif
|
# endif
|
||||||
while (len >= 16) {
|
while (len >= 16) {
|
||||||
(*block) (ivec, ecount_buf, key);
|
(*block) (ivec, ecount_buf, key);
|
||||||
ctr128_inc_aligned(ivec);
|
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 *)(out + n) =
|
||||||
*(size_t *)(in + n) ^ *(size_t *)(ecount_buf + n);
|
*(size_t *)(in + n) ^ *(size_t *)(ecount_buf + n);
|
||||||
len -= 16;
|
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 */
|
/* increment upper 96 bits of 128-bit counter by 1 */
|
||||||
static void ctr96_inc(unsigned char *counter)
|
static void ctr96_inc(unsigned char *counter)
|
||||||
{
|
{
|
||||||
u32 n = 12;
|
u32 n = 12, c = 1;
|
||||||
u8 c;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
--n;
|
--n;
|
||||||
c = counter[n];
|
c += counter[n];
|
||||||
++c;
|
counter[n] = (u8)c;
|
||||||
counter[n] = c;
|
c >>= 8;
|
||||||
if (c)
|
|
||||||
return;
|
|
||||||
} while (n);
|
} while (n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue