|
@@ -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;
|
|
|
}
|