Index: monitor.c
===================================================================
RCS file: /usr/local/src/security/openssh/cvs/openssh/monitor.c,v
retrieving revision 1.149
diff -u -p -r1.149 monitor.c
--- monitor.c	20 Jun 2011 04:42:23 -0000	1.149
+++ monitor.c	29 Jul 2011 11:36:04 -0000
@@ -570,8 +570,7 @@ monitor_read(struct monitor *pmonitor, s
 
 	buffer_init(&m);
 
-	mm_request_receive(pmonitor->m_sendfd, &m);
-	type = buffer_get_char(&m);
+	type = mm_request_receive(pmonitor->m_sendfd, &m);
 
 	debug3("%s: checking request %d", __func__, type);
 
@@ -1988,6 +1987,8 @@ monitor_init(void)
 		mm_init_compression(mon->m_zlib);
 	}
 
+	mm_init_encryption();
+
 	return mon;
 }
 
@@ -1995,6 +1996,7 @@ void
 monitor_reinit(struct monitor *mon)
 {
 	monitor_openfds(mon, 0);
+	mm_init_encryption();
 }
 
 #ifdef GSSAPI
Index: monitor.h
===================================================================
RCS file: /usr/local/src/security/openssh/cvs/openssh/monitor.h,v
retrieving revision 1.23
diff -u -p -r1.23 monitor.h
--- monitor.h	20 Jun 2011 04:42:23 -0000	1.23
+++ monitor.h	29 Jul 2011 10:23:00 -0000
@@ -93,7 +93,7 @@ int monitor_read(struct monitor*, struct
 
 /* Prototypes for request sending and receiving */
 void mm_request_send(int, enum monitor_reqtype, Buffer *);
-void mm_request_receive(int, Buffer *);
+u_char mm_request_receive(int, Buffer *);
 void mm_request_receive_expect(int, enum monitor_reqtype, Buffer *);
 
 #endif /* _MONITOR_H_ */
Index: monitor_wrap.c
===================================================================
RCS file: /usr/local/src/security/openssh/cvs/openssh/monitor_wrap.c,v
retrieving revision 1.89
diff -u -p -r1.89 monitor_wrap.c
--- monitor_wrap.c	20 Jun 2011 04:42:23 -0000	1.89
+++ monitor_wrap.c	29 Jul 2011 15:33:08 -0000
@@ -41,6 +41,7 @@
 #include <openssl/bn.h>
 #include <openssl/dh.h>
 #include <openssl/evp.h>
+#include <openssl/rand.h>
 
 #include "openbsd-compat/sys-queue.h"
 #include "xmalloc.h"
@@ -69,6 +70,7 @@
 #endif
 #include "monitor_wrap.h"
 #include "atomicio.h"
+#include "cipher.h"
 #include "monitor_fdpass.h"
 #include "misc.h"
 #include "schnorr.h"
@@ -88,6 +90,12 @@ extern struct monitor *pmonitor;
 extern Buffer loginmsg;
 extern ServerOptions options;
 
+static u_char *monitor_padding;
+static Cipher *monitor_cipher;
+static CipherContext monitor_encrypt_ctx;
+static CipherContext monitor_decrypt_ctx;
+static int encrypt_enabled;
+
 void
 mm_log_handler(LogLevel level, const char *msg, void *ctx)
 {
@@ -124,27 +132,103 @@ mm_is_monitor(void)
 	return (pmonitor && pmonitor->m_pid > 0);
 }
 
+/* called before fork */
+void
+mm_init_encryption(void)
+{
+	size_t keylen, blocksize;
+	u_char *key;
+
+	debug3("mm_init_encryption");
+	encrypt_enabled = 0;
+	if (monitor_cipher == NULL &&
+	    ((monitor_cipher = cipher_by_name("aes128-cbc")) == NULL))
+		fatal("mm_init_encryption: no aes128-cbc cipher");
+	keylen = cipher_keylen(monitor_cipher);
+	blocksize = cipher_blocksize(monitor_cipher);
+	key = xmalloc(keylen);
+	if (RAND_bytes(key, keylen) != 1) {
+		error("mm_init_encryption: no random bytes available");
+		xfree(key);
+		return;
+	}
+	cipher_init(&monitor_encrypt_ctx, monitor_cipher, key, keylen, NULL,
+	    0, CIPHER_ENCRYPT);
+	cipher_init(&monitor_decrypt_ctx, monitor_cipher, key, keylen, NULL,
+	    0, CIPHER_DECRYPT);
+	bzero(key, keylen);
+	if (monitor_padding == NULL) {
+		monitor_padding = xmalloc(blocksize);
+		bzero(monitor_padding, cipher_blocksize(monitor_cipher));
+	}
+	encrypt_enabled = 1;
+}
+
+/* returns padding length appended to end of buffer */
+u_char
+mm_encrypt(Buffer *m)
+{
+	u_char pad_len, *dest;
+	size_t len, block_size = cipher_blocksize(monitor_cipher);
+
+	debug3("mm_encrypt data_len %d", buffer_len(m));
+	/* append required padding */
+	pad_len = block_size - (buffer_len(m) % block_size);
+	buffer_append(m, monitor_padding, pad_len);
+	/* encrypt and replace in buffer */
+	len = buffer_len(m);
+	dest = xmalloc(len);
+	cipher_crypt(&monitor_encrypt_ctx, dest, buffer_ptr(m), len);
+	buffer_clear(m);
+	buffer_append(m, dest, len);
+	bzero(dest, len);
+	xfree(dest);
+	return pad_len;
+}
+
+void
+mm_decrypt(Buffer *m, u_char pad_len)
+{
+	u_char *dest;
+	u_int len = buffer_len(m);
+
+	debug3("mm_decrypt padded length %d padding %u", buffer_len(m), pad_len);
+	/* decrypt and replace in buffer */
+	dest = xmalloc(len);
+	cipher_crypt(&monitor_decrypt_ctx, dest, buffer_ptr(m), len);
+	buffer_clear(m);
+	buffer_append(m, dest, len);
+	bzero(dest, len);
+	xfree(dest);
+	/* remove padding */
+	buffer_consume_end(m, pad_len);
+}
+
 void
 mm_request_send(int sock, enum monitor_reqtype type, Buffer *m)
 {
-	u_int mlen = buffer_len(m);
-	u_char buf[5];
+	u_int mlen;
+	u_char buf[6], pad_len = 0;
 
 	debug3("%s entering: type %d", __func__, type);
 
-	put_u32(buf, mlen + 1);
+	if (encrypt_enabled)
+		pad_len = mm_encrypt(m);
+	mlen = buffer_len(m);
+	put_u32(buf, mlen);
 	buf[4] = (u_char) type;		/* 1st byte of payload is mesg-type */
+	buf[5] = pad_len;		/* bytes of padding appended */
 	if (atomicio(vwrite, sock, buf, sizeof(buf)) != sizeof(buf))
 		fatal("%s: write: %s", __func__, strerror(errno));
 	if (atomicio(vwrite, sock, buffer_ptr(m), mlen) != mlen)
 		fatal("%s: write: %s", __func__, strerror(errno));
 }
 
-void
+u_char
 mm_request_receive(int sock, Buffer *m)
 {
-	u_char buf[4];
-	u_int msg_len;
+	u_char type, buf[6];
+	u_int msg_len, pad_len = 0;
 
 	debug3("%s entering", __func__);
 
@@ -154,12 +238,17 @@ mm_request_receive(int sock, Buffer *m)
 		fatal("%s: read: %s", __func__, strerror(errno));
 	}
 	msg_len = get_u32(buf);
+	type = buf[4];
+	pad_len = buf[5];
 	if (msg_len > 256 * 1024)
 		fatal("%s: read: bad msg_len %d", __func__, msg_len);
 	buffer_clear(m);
 	buffer_append_space(m, msg_len);
 	if (atomicio(read, sock, buffer_ptr(m), msg_len) != msg_len)
 		fatal("%s: read: %s", __func__, strerror(errno));
+	if (encrypt_enabled)
+		mm_decrypt(m, pad_len);
+	return type;
 }
 
 void
@@ -169,8 +258,7 @@ mm_request_receive_expect(int sock, enum
 
 	debug3("%s entering: type %d", __func__, type);
 
-	mm_request_receive(sock, m);
-	rtype = buffer_get_char(m);
+	rtype = mm_request_receive(sock, m);
 	if (rtype != type)
 		fatal("%s: read: rtype %d != type %d", __func__,
 		    rtype, type);
Index: monitor_wrap.h
===================================================================
RCS file: /usr/local/src/security/openssh/cvs/openssh/monitor_wrap.h,v
retrieving revision 1.30
diff -u -p -r1.30 monitor_wrap.h
--- monitor_wrap.h	20 Jun 2011 04:42:23 -0000	1.30
+++ monitor_wrap.h	29 Jul 2011 11:51:14 -0000
@@ -38,6 +38,7 @@ struct mm_master;
 struct Authctxt;
 
 void mm_log_handler(LogLevel, const char *, void *);
+void mm_init_encryption(void);
 int mm_is_monitor(void);
 DH *mm_choose_dh(int, int, int);
 int mm_key_sign(Key *, u_char **, u_int *, u_char *, u_int);
