--- aes_cfb.c.prev	2006-05-25 15:34:04.000000000 +1000
+++ aes_cfb.c	2006-05-26 14:27:43.000000000 +1000
@@ -125,34 +125,69 @@
 	const unsigned long length, const AES_KEY *key,
 	unsigned char *ivec, int *num, const int enc) {
 
+#define u64 unsigned long long
 	unsigned int n;
-	unsigned long l = length;
+	unsigned long l = 0;
 	unsigned char c;
+	u64 c8;
 
 	assert(in && out && key && ivec && num);
 
 	n = *num;
 
 	if (enc) {
-		while (l--) {
-			if (n == 0) {
-				AES_encrypt(ivec, ivec, key);
+		if (n) {
+			for (; l < length; l++) {
+				ivec[n] = out[l] = ivec[n] ^ in[l];
+				if(!(n = (n + 1) % AES_BLOCK_SIZE)) {
+					l++;
+					break;
+				}
 			}
-			ivec[n] = *(out++) = *(in++) ^ ivec[n];
-			n = (n+1) % AES_BLOCK_SIZE;
 		}
+
+		for (; l + sizeof(u64) <= length; l += sizeof(u64)) {
+			if(!n) AES_encrypt(ivec, ivec, key);
+			*(u64*)(out + l) = *(u64*)(ivec + n) ^ *(u64*)(in + l);
+			*(u64*)(ivec + n) = *(u64*)(out + l);
+			n = (n + sizeof(u64)) % AES_BLOCK_SIZE;
+		}
+
+		if((length - l) && !n) AES_encrypt(ivec, ivec, key);
+		for (; l < length; l++) {
+			ivec[n] = out[l] = ivec[n] ^ in[l];
+			n = (n + 1) % AES_BLOCK_SIZE;
+		}
+
 	} else {
-		while (l--) {
-			if (n == 0) {
-				AES_encrypt(ivec, ivec, key);
+		if (n) {
+			for (; l < length; l++) {
+				c = in[l];
+				out[l] = ivec[n] ^ in[l];
+				ivec[n] = c;
+				if(!(n = (n + 1) % AES_BLOCK_SIZE)) {
+					l++;
+					break;
+				}
 			}
-			c = *(in);
-			*(out++) = *(in++) ^ ivec[n];
+		}
+
+		for (; l + sizeof(u64) <= length; l += sizeof(u64)) {
+			if(!n) AES_encrypt(ivec, ivec, key);
+			c8 = *(u64*)(in + l);
+			*(u64*)(out + l) = *(u64*)(ivec + n) ^ *(u64*)(in + l);
+			*(u64*)(ivec + n) = c8;
+			n = (n + sizeof(u64)) % AES_BLOCK_SIZE;
+		}
+
+		if((length - l) && !n) AES_encrypt(ivec, ivec, key);
+		for (; l < length; l++) {
+			c = in[l];
+			out[l] = ivec[n] ^ in[l];
 			ivec[n] = c;
-			n = (n+1) % AES_BLOCK_SIZE;
+			n = (n + 1) % AES_BLOCK_SIZE;
 		}
 	}
-
 	*num=n;
 }
 
