RC4: Fix invalid read.
[paraslash.git] / crypt.c
diff --git a/crypt.c b/crypt.c
index 49e9e8ae7863fed3f40881a356957f115bf31769..cdcb6149d04254a0def3bcc903823f71ae3a89e5 100644 (file)
--- a/crypt.c
+++ b/crypt.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005-2009 Andre Noll <maan@systemlinux.org>
+ * Copyright (C) 2005-2011 Andre Noll <maan@systemlinux.org>
  *
  * Licensed under the GPL v2. For licencing details see COPYING.
  */
@@ -203,6 +203,8 @@ int para_encrypt_buffer(RSA *rsa, unsigned char *inbuf,
        return ret < 0? -E_ENCRYPT : ret;
 }
 
+#define RC4_ALIGN 8
+
 /**
  * Encrypt and send a buffer.
  *
@@ -218,10 +220,16 @@ int rc4_send_bin_buffer(struct rc4_context *rc4c, const char *buf, size_t len)
 {
        int ret;
        unsigned char *tmp;
+       static unsigned char remainder[RC4_ALIGN];
+       size_t l1 = ROUND_DOWN(len, RC4_ALIGN), l2 = ROUND_UP(len, RC4_ALIGN);
 
        assert(len);
-       tmp = para_malloc(len);
-       RC4(&rc4c->send_key, len, (const unsigned char *)buf, tmp);
+       tmp = para_malloc(l2);
+       RC4(&rc4c->send_key, l1, (const unsigned char *)buf, tmp);
+       if (len > l1) {
+               memcpy(remainder, buf + l1, len - l1);
+               RC4(&rc4c->send_key, len - l1, remainder, tmp + l1);
+       }
        ret = write_all(rc4c->fd, (char *)tmp, &len);
        free(tmp);
        return ret;