| 
					
				 | 
			
			
				@@ -1,10 +1,12 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-/* Reference code from the Intel AES-NI whitepaper 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* Based on reference code from the Intel AES-NI whitepaper 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  * http://www.intel.com/content/dam/doc/white-paper/advanced-encryption-standard-new-instructions-set-paper.pdf 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <wmmintrin.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-inline __m128i AES_128_ASSIST (__m128i temp1, __m128i temp2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+using AESkey = __m128i[11]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline __m128i AES_128_ASSIST (__m128i temp1, __m128i temp2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     __m128i temp3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     temp2 = _mm_shuffle_epi32 (temp2 ,0xff); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -18,12 +20,11 @@ inline __m128i AES_128_ASSIST (__m128i temp1, __m128i temp2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return temp1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-void AES_128_Key_Expansion (const unsigned char *userkey, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    unsigned char *key) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline void AES_128_Key_Expansion (AESkey &key, __m128i rawkey) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     __m128i temp1, temp2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    __m128i *Key_Schedule = (__m128i*)key; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    temp1 = _mm_loadu_si128((__m128i*)userkey); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    __m128i *Key_Schedule = key; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    temp1 = rawkey; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     Key_Schedule[0] = temp1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     temp2 = _mm_aeskeygenassist_si128 (temp1 ,0x1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     temp1 = AES_128_ASSIST(temp1, temp2); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -57,26 +58,15 @@ void AES_128_Key_Expansion (const unsigned char *userkey, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     Key_Schedule[10] = temp1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-/* Note – the length of the output buffer is assumed to be a multiple of 16 bytes */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-void AES_ECB_encrypt(const unsigned char *in, //pointer to the PLAINTEXT 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    unsigned char *out, //pointer to the CIPHERTEXT buffer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    unsigned long length, //text length in bytes 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const char *key, //pointer to the expanded key schedule 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    int number_of_rounds) //number of AES rounds 10,12 or 14 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline void AES_ECB_encrypt(__m128i &ciphertext, __m128i plaintext, const AESkey &key) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     __m128i tmp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    int i,j; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if(length%16) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        length = length/16+1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        length = length/16; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for(i=0; i < length; i++){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        tmp = _mm_loadu_si128 (&((__m128i*)in)[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        tmp = _mm_xor_si128 (tmp,((__m128i*)key)[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for(j=1; j <number_of_rounds; j++){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            tmp = _mm_aesenc_si128 (tmp,((__m128i*)key)[j]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        tmp = _mm_aesenclast_si128 (tmp,((__m128i*)key)[j]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        _mm_storeu_si128 (&((__m128i*)out)[i],tmp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    int j; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tmp = plaintext; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tmp = _mm_xor_si128 (tmp,key[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for(j=1; j<10; j++){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        tmp = _mm_aesenc_si128 (tmp,key[j]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tmp = _mm_aesenclast_si128 (tmp,key[j]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ciphertext=tmp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |