From 802266603cce119af8f1945c8a6a944e47363637 Mon Sep 17 00:00:00 2001 From: jsing Date: Wed, 21 Oct 2015 16:36:50 +0000 Subject: [PATCH] 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 - thanks! ok beck@ miod@ --- lib/libcrypto/rc4/rc4_enc.c | 64 +---------------------------- lib/libssl/src/crypto/rc4/rc4_enc.c | 64 +---------------------------- 2 files changed, 2 insertions(+), 126 deletions(-) diff --git a/lib/libcrypto/rc4/rc4_enc.c b/lib/libcrypto/rc4/rc4_enc.c index 57975a95ae2..4dacf3f7089 100644 --- a/lib/libcrypto/rc4/rc4_enc.c +++ b/lib/libcrypto/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 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 -- 2.20.1