summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2015-10-21 16:36:51 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2015-10-21 16:36:51 +0000
commite406b8d2b07fd632185dfda31ba70efbfe6766ee (patch)
tree5be4c14b8130bcfff1bfe70a34df166ef179acae
parentc845cd430790ce324139347c44bb6341813d23b8 (diff)
In the case where len is not a multiple of sizeof(RC4_CHUNK) the RC4 code
will end up doing a read and write of up to 7 bytes beyond the specified length. This is effectively a non-issue since we read and write back the same data and due to alignment it is within a page boundary. Regardless, avoid this by removing the "special" handling for the remaining length and allow the standard (non-chunk) code to process the remaining bytes, which does not result in overrun. Reported by Pascal Cuoq <cuoq at trust-in-soft.com> - thanks! ok beck@ miod@
-rw-r--r--lib/libssl/src/crypto/rc4/rc4_enc.c64
1 files changed, 1 insertions, 63 deletions
diff --git a/lib/libssl/src/crypto/rc4/rc4_enc.c b/lib/libssl/src/crypto/rc4/rc4_enc.c
index 57975a95ae2..4dacf3f7089 100644
--- a/lib/libssl/src/crypto/rc4/rc4_enc.c
+++ b/lib/libssl/src/crypto/rc4/rc4_enc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rc4_enc.c,v 1.14 2015/10/20 15:50:13 jsing Exp $ */
+/* $OpenBSD: rc4_enc.c,v 1.15 2015/10/21 16:36:50 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -168,37 +168,6 @@ RC4(RC4_KEY *key, size_t len, const unsigned char *indata,
indata += sizeof(RC4_CHUNK);
outdata += sizeof(RC4_CHUNK);
}
- if (len) {
- RC4_CHUNK mask = (RC4_CHUNK) - 1, ochunk;
-
- ichunk = *(RC4_CHUNK *)indata;
- ochunk = *(RC4_CHUNK *)outdata;
- otp = 0;
- i = BESHFT(0);
- mask <<= (sizeof(RC4_CHUNK) - len) << 3;
- switch (len & (sizeof(RC4_CHUNK) - 1)) {
- case 7:
- otp = RC4_STEP << i, i -= 8;
- case 6:
- otp |= RC4_STEP << i, i -= 8;
- case 5:
- otp |= RC4_STEP << i, i -= 8;
- case 4:
- otp |= RC4_STEP << i, i -= 8;
- case 3:
- otp |= RC4_STEP << i, i -= 8;
- case 2:
- otp |= RC4_STEP << i, i -= 8;
- case 1:
- otp |= RC4_STEP << i, i -= 8;
- }
- ochunk &= ~mask;
- ochunk |= (otp ^ ichunk) & mask;
- *(RC4_CHUNK *)outdata = ochunk;
- }
- key->x = x;
- key->y = y;
- return;
} else { /* LITTLE-ENDIAN CASE */
# define LESHFT(c) (((c)*8)&(sizeof(RC4_CHUNK)*8-1))
for (; len & (0 - sizeof(RC4_CHUNK)); len -= sizeof(RC4_CHUNK)) {
@@ -217,37 +186,6 @@ RC4(RC4_KEY *key, size_t len, const unsigned char *indata,
indata += sizeof(RC4_CHUNK);
outdata += sizeof(RC4_CHUNK);
}
- if (len) {
- RC4_CHUNK mask = (RC4_CHUNK) - 1, ochunk;
-
- ichunk = *(RC4_CHUNK *)indata;
- ochunk = *(RC4_CHUNK *)outdata;
- otp = 0;
- i = 0;
- mask >>= (sizeof(RC4_CHUNK) - len) << 3;
- switch (len&(sizeof(RC4_CHUNK) - 1)) {
- case 7:
- otp = RC4_STEP, i += 8;
- case 6:
- otp |= RC4_STEP << i, i += 8;
- case 5:
- otp |= RC4_STEP << i, i += 8;
- case 4:
- otp |= RC4_STEP << i, i += 8;
- case 3:
- otp |= RC4_STEP << i, i += 8;
- case 2:
- otp |= RC4_STEP << i, i += 8;
- case 1:
- otp |= RC4_STEP << i, i += 8;
- }
- ochunk &= ~mask;
- ochunk |= (otp ^ ichunk) & mask;
- *(RC4_CHUNK *)outdata = ochunk;
- }
- key->x = x;
- key->y = y;
- return;
}
}
#endif