Petr Šabata 81d24c
diff -up openssh-5.9p1/cipher-ctr.c.ctr-evp openssh-5.9p1/cipher-ctr.c
Petr Šabata 81d24c
--- openssh-5.9p1/cipher-ctr.c.ctr-evp	2012-01-11 09:24:06.000000000 +0100
Petr Šabata 81d24c
+++ openssh-5.9p1/cipher-ctr.c	2012-01-11 15:54:04.675956600 +0100
Petr Šabata 81d24c
@@ -38,7 +38,7 @@ void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, in
Petr Šabata 81d24c
 
Petr Šabata 81d24c
 struct ssh_aes_ctr_ctx
Petr Šabata 81d24c
 {
Petr Šabata 81d24c
-	AES_KEY		aes_ctx;
Petr Šabata 81d24c
+	EVP_CIPHER_CTX	ecbctx;
Petr Šabata 81d24c
 	u_char		aes_counter[AES_BLOCK_SIZE];
Petr Šabata 81d24c
 };
Petr Šabata 81d24c
 
Petr Šabata 81d24c
@@ -63,21 +63,42 @@ ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char
Petr Šabata 81d24c
 {
Petr Šabata 81d24c
 	struct ssh_aes_ctr_ctx *c;
Petr Šabata 81d24c
 	size_t n = 0;
Petr Šabata 81d24c
-	u_char buf[AES_BLOCK_SIZE];
Petr Šabata 81d24c
+	u_char ctrbuf[AES_BLOCK_SIZE*256];
Petr Šabata 81d24c
+	u_char buf[AES_BLOCK_SIZE*256];
Petr Šabata 81d24c
 
Petr Šabata 81d24c
 	if (len == 0)
Petr Šabata 81d24c
 		return (1);
Petr Šabata 81d24c
 	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
Petr Šabata 81d24c
 		return (0);
Petr Šabata 81d24c
 
Petr Šabata 81d24c
-	while ((len--) > 0) {
Petr Šabata 81d24c
+	for (; len > 0; len -= sizeof(u_int)) {
Petr Šabata 81d24c
+		u_int r,a,b;
Petr Šabata 81d24c
+
Petr Šabata 81d24c
 		if (n == 0) {
Petr Šabata 81d24c
-			AES_encrypt(c->aes_counter, buf, &c->aes_ctx);
Petr Šabata 81d24c
-			ssh_ctr_inc(c->aes_counter, AES_BLOCK_SIZE);
Petr Šabata 81d24c
+			int outl, i, buflen;
Petr Šabata 81d24c
+
Petr Šabata 81d24c
+			buflen = MIN(len, sizeof(ctrbuf));
Petr Šabata 81d24c
+
Petr Šabata 81d24c
+			for(i = 0; i < buflen; i += AES_BLOCK_SIZE) {
Petr Šabata 81d24c
+				memcpy(&ctrbuf[i], c->aes_counter, AES_BLOCK_SIZE);
Petr Šabata 81d24c
+				ssh_ctr_inc(c->aes_counter, AES_BLOCK_SIZE);
Petr Šabata 81d24c
+			}
Petr Šabata 81d24c
+
Petr Šabata 81d24c
+			EVP_EncryptUpdate(&c->ecbctx, buf, &outl,
Petr Šabata 81d24c
+				ctrbuf, buflen);
Petr Šabata 81d24c
 		}
Petr Šabata 81d24c
-		*(dest++) = *(src++) ^ buf[n];
Petr Šabata 81d24c
-		n = (n + 1) % AES_BLOCK_SIZE;
Petr Šabata 81d24c
+
Petr Šabata 81d24c
+		memcpy(&a, src, sizeof(a));
Petr Šabata 81d24c
+		memcpy(&b, &buf[n], sizeof(b));
Petr Šabata 81d24c
+		r = a ^ b;
Petr Šabata 81d24c
+		memcpy(dest, &r, sizeof(r));
Petr Šabata 81d24c
+		src += sizeof(a);
Petr Šabata 81d24c
+		dest += sizeof(r);
Petr Šabata 81d24c
+
Petr Šabata 81d24c
+		n = (n + sizeof(b)) % sizeof(buf);
Petr Šabata 81d24c
 	}
Petr Šabata 81d24c
+	memset(ctrbuf, '\0', sizeof(ctrbuf));
Petr Šabata 81d24c
+	memset(buf, '\0', sizeof(buf));
Petr Šabata 81d24c
 	return (1);
Petr Šabata 81d24c
 }
Petr Šabata 81d24c
 
Petr Šabata 81d24c
@@ -91,9 +112,28 @@ ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, co
Petr Šabata 81d24c
 		c = xmalloc(sizeof(*c));
Petr Šabata 81d24c
 		EVP_CIPHER_CTX_set_app_data(ctx, c);
Petr Šabata 81d24c
 	}
Petr Šabata 81d24c
-	if (key != NULL)
Petr Šabata 81d24c
-		AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
Petr Šabata 81d24c
-		    &c->aes_ctx);
Petr Šabata 81d24c
+
Petr Šabata 81d24c
+	EVP_CIPHER_CTX_init(&c->ecbctx);
Petr Šabata 81d24c
+
Petr Šabata 81d24c
+	if (key != NULL) {
Petr Šabata 81d24c
+		const EVP_CIPHER *cipher;
Petr Šabata 81d24c
+		switch(EVP_CIPHER_CTX_key_length(ctx)*8) {
Petr Šabata 81d24c
+			case 128:
Petr Šabata 81d24c
+				cipher = EVP_aes_128_ecb();
Petr Šabata 81d24c
+				break;
Petr Šabata 81d24c
+			case 192:
Petr Šabata 81d24c
+				cipher = EVP_aes_192_ecb();
Petr Šabata 81d24c
+				break;
Petr Šabata 81d24c
+			case 256:
Petr Šabata 81d24c
+				cipher = EVP_aes_256_ecb();
Petr Šabata 81d24c
+				break;
Petr Šabata 81d24c
+			default:
Petr Šabata 81d24c
+				fatal("ssh_aes_ctr_init: wrong aes key length");
Petr Šabata 81d24c
+		}
Petr Šabata 81d24c
+		if(!EVP_EncryptInit_ex(&c->ecbctx, cipher, NULL, key, NULL))
Petr Šabata 81d24c
+			fatal("ssh_aes_ctr_init: cannot initialize aes encryption");
Petr Šabata 81d24c
+		EVP_CIPHER_CTX_set_padding(&c->ecbctx, 0);
Petr Šabata 81d24c
+	}
Petr Šabata 81d24c
 	if (iv != NULL)
Petr Šabata 81d24c
 		memcpy(c->aes_counter, iv, AES_BLOCK_SIZE);
Petr Šabata 81d24c
 	return (1);
Petr Šabata 81d24c
@@ -105,6 +145,7 @@ ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx)
Petr Šabata 81d24c
 	struct ssh_aes_ctr_ctx *c;
Petr Šabata 81d24c
 
Petr Šabata 81d24c
 	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
Petr Šabata 81d24c
+		EVP_CIPHER_CTX_cleanup(&c->ecbctx);
Petr Šabata 81d24c
 		memset(c, 0, sizeof(*c));
Petr Šabata 81d24c
 		free(c);
Petr Šabata 81d24c
 		EVP_CIPHER_CTX_set_app_data(ctx, NULL);