| 
					
				 | 
			
			
				@@ -20,12 +20,23 @@ const char aes_c_id[] = "$Id$"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <string.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "aes.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "util.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "log.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /* Use OpenSSL's AES if we're running 0.9.7 or later.  (The f at the end of 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  * the version below means "release"; see opensslv.h) */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #if OPENSSL_VERSION_NUMBER >= 0x0090700fl 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #define USE_OPENSSL_AES 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <openssl/aes.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <openssl/evp.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* For now, if OpenSSL supports AES, we always use the EVP_CIPHER_CTX version 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * of it, so OpenSSL can use an engine instead if available.  If the overhead 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * turns out to suck, we should maybe switch to use OpenSSL's AES directly 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * when no engine exists. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#ifdef USE_OPENSSL_AES 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define USE_OPENSSL_EVP 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /*======================================================================*/ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -48,7 +59,9 @@ static void rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /* Interface to AES code, and counter implementation */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 struct aes_cnt_cipher { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#ifdef USE_OPENSSL_AES 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#if defined(USE_OPENSSL_EVP) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  EVP_CIPHER_CTX key; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#elif defined(USE_OPENSSL_AES) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   AES_KEY key; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   u32 rk[4*(MAXNR+1)]; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -67,6 +80,12 @@ struct aes_cnt_cipher { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 _aes_fill_buf(aes_cnt_cipher_t *cipher) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* We don't currently use OpenSSL's counter mode implementation because: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *  1) some versions have known bugs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *  2) its attitude towards IVs is not our own 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *  3) changing the counter position was not trivial, last time I looked. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * None of these issues are insurmountable in principle. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   u32 counter0 = cipher->counter0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   u32 counter1 = cipher->counter1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   u8 buf[16]; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -80,8 +99,13 @@ _aes_fill_buf(aes_cnt_cipher_t *cipher) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   buf[ 9] = (counter1 >> 16) & 0xff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   buf[ 8] = (counter1 >> 24) & 0xff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#ifdef USE_OPENSSL_AES 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  AES_encrypt(buf, cipher->buf, &(cipher->key)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#if defined(USE_OPENSSL_EVP) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    int outl=16, inl=16; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    EVP_EncryptUpdate(&cipher->key, cipher->buf, &outl, buf, inl); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#elif defined(USE_OPENSSL_AES) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AES_encrypt(buf, cipher->buf, &cipher->key); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   rijndaelEncrypt(cipher->rk, cipher->nr, buf, cipher->buf); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -105,7 +129,16 @@ aes_new_cipher() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 aes_set_key(aes_cnt_cipher_t *cipher, const char *key, int key_bits) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#ifdef USE_OPENSSL_AES 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#if defined(USE_OPENSSL_EVP) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const EVP_CIPHER *c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  switch (key_bits) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    case 128: c = EVP_aes_128_ecb(); break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    case 192: c = EVP_aes_192_ecb(); break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    case 256: c = EVP_aes_256_ecb(); break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    default: tor_assert(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  EVP_EncryptInit(&cipher->key, c, (const unsigned char*)key, NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#elif defined(USE_OPENSSL_AES) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   AES_set_encrypt_key((const unsigned char *)key, key_bits, &(cipher->key)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   cipher->nr = rijndaelKeySetupEnc(cipher->rk, (const unsigned char*)key, 
			 |