From 78efdb4f3ff136775cd3c27d27f23d36605e0d50 Mon Sep 17 00:00:00 2001 From: Matteo B Date: Fri, 15 May 2020 16:45:35 -0700 Subject: [PATCH] Adding ECB and CBC modes via AES-NI (#32) Added ECB and CBC modes via AES-NI, only is enabled and supported --- aesni/aesni-enc-cbc.c | 60 +++++++++++ aesni/aesni-enc-ecb.c | 58 ++++++++++ aesni/aesni-key-exp.c | 196 ++++++++++++++++++++++++++++++++++ main.cpp | 4 +- qaesencryption.cpp | 239 ++++++++++++++++++++++++++++++------------ qaesencryption.h | 8 ++ qaesencryption.pro | 16 ++- unit_test/aestest.cpp | 4 + 8 files changed, 512 insertions(+), 73 deletions(-) create mode 100755 aesni/aesni-enc-cbc.c create mode 100755 aesni/aesni-enc-ecb.c create mode 100755 aesni/aesni-key-exp.c diff --git a/aesni/aesni-enc-cbc.c b/aesni/aesni-enc-cbc.c new file mode 100755 index 0000000..5efceb1 --- /dev/null +++ b/aesni/aesni-enc-cbc.c @@ -0,0 +1,60 @@ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void AES_CBC_encrypt(const unsigned char *in, + unsigned char *out, + unsigned char ivec[16], + unsigned long length, + const char *key, + int number_of_rounds) +{ + __m128i feedback,data; + unsigned long i; + int j; + if (length%16) + length = length/16+1; + else length /=16; + feedback=_mm_loadu_si128 ((__m128i*)ivec); + for(i=0; i < length; i++) { + data = _mm_loadu_si128 (&((__m128i*)in)[i]); + feedback = _mm_xor_si128 (data,feedback); + feedback = _mm_xor_si128 (feedback,((__m128i*)key)[0]); + for(j=1; j + +#ifdef __cplusplus +extern "C" { +#endif + +/* 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 +{ + __m128i tmp; + unsigned long i; + int 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 + +#ifdef __cplusplus +extern "C" { +#endif + +#define cpuid(func, ax, bx, cx, dx)\ + __asm__ __volatile__("cpuid": "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) : "a" (func)); + +inline bool check_aesni_support() +{ + unsigned int a,b,c,d; + cpuid(1, a,b,c,d); + return (c & 0x2000000); +} +inline __m128i AES_128_ASSIST (__m128i temp1, __m128i temp2) +{ + __m128i temp3; + temp2 = _mm_shuffle_epi32 (temp2 ,0xff); + temp3 = _mm_slli_si128 (temp1, 0x4); + temp1 = _mm_xor_si128 (temp1, temp3); + temp3 = _mm_slli_si128 (temp3, 0x4); + temp1 = _mm_xor_si128 (temp1, temp3); + temp3 = _mm_slli_si128 (temp3, 0x4); + temp1 = _mm_xor_si128 (temp1, temp3); + temp1 = _mm_xor_si128 (temp1, temp2); + return temp1; +} + +void AES_128_Key_Expansion (const unsigned char *userkey, + unsigned char *key) +{ + __m128i temp1, temp2; + __m128i *Key_Schedule = (__m128i*)key; + temp1 = _mm_loadu_si128((__m128i*)userkey); + Key_Schedule[0] = temp1; + temp2 = _mm_aeskeygenassist_si128 (temp1 ,0x1); + temp1 = AES_128_ASSIST(temp1, temp2); + Key_Schedule[1] = temp1; + temp2 = _mm_aeskeygenassist_si128 (temp1,0x2); + temp1 = AES_128_ASSIST(temp1, temp2); + Key_Schedule[2] = temp1; + temp2 = _mm_aeskeygenassist_si128 (temp1,0x4); + temp1 = AES_128_ASSIST(temp1, temp2); + Key_Schedule[3] = temp1; + temp2 = _mm_aeskeygenassist_si128 (temp1,0x8); + temp1 = AES_128_ASSIST(temp1, temp2); + Key_Schedule[4] = temp1; + temp2 = _mm_aeskeygenassist_si128 (temp1,0x10); + temp1 = AES_128_ASSIST(temp1, temp2); + Key_Schedule[5] = temp1; + temp2 = _mm_aeskeygenassist_si128 (temp1,0x20); + temp1 = AES_128_ASSIST(temp1, temp2); + Key_Schedule[6] = temp1; + temp2 = _mm_aeskeygenassist_si128 (temp1,0x40); + temp1 = AES_128_ASSIST(temp1, temp2); + Key_Schedule[7] = temp1; + temp2 = _mm_aeskeygenassist_si128 (temp1,0x80); + temp1 = AES_128_ASSIST(temp1, temp2); + Key_Schedule[8] = temp1; + temp2 = _mm_aeskeygenassist_si128 (temp1,0x1b); + temp1 = AES_128_ASSIST(temp1, temp2); + Key_Schedule[9] = temp1; + temp2 = _mm_aeskeygenassist_si128 (temp1,0x36); + temp1 = AES_128_ASSIST(temp1, temp2); + Key_Schedule[10] = temp1; +} + +inline void KEY_192_ASSIST(__m128i* temp1, __m128i * temp2, __m128i * temp3) +{ + __m128i temp4; + *temp2 = _mm_shuffle_epi32 (*temp2, 0x55); + temp4 = _mm_slli_si128 (*temp1, 0x4); + *temp1 = _mm_xor_si128 (*temp1, temp4); + temp4 = _mm_slli_si128 (temp4, 0x4); + *temp1 = _mm_xor_si128 (*temp1, temp4); + temp4 = _mm_slli_si128 (temp4, 0x4); + *temp1 = _mm_xor_si128 (*temp1, temp4); + *temp1 = _mm_xor_si128 (*temp1, *temp2); + *temp2 = _mm_shuffle_epi32(*temp1, 0xff); + temp4 = _mm_slli_si128 (*temp3, 0x4); + *temp3 = _mm_xor_si128 (*temp3, temp4); + *temp3 = _mm_xor_si128 (*temp3, *temp2); +} + +void AES_192_Key_Expansion (const unsigned char *userkey, unsigned char *key) +{ + __m128i temp1, temp2, temp3; + __m128i *Key_Schedule = (__m128i*)key; + temp1 = _mm_loadu_si128((__m128i*)userkey); + temp3 = _mm_loadu_si128((__m128i*)(userkey+16)); + Key_Schedule[0]=temp1; Key_Schedule[1]=temp3; + temp2=_mm_aeskeygenassist_si128 (temp3,0x1); + KEY_192_ASSIST(&temp1, &temp2, &temp3); + Key_Schedule[1] = (__m128i)_mm_shuffle_pd((__m128d)Key_Schedule[1], (__m128d)temp1,0); + Key_Schedule[2] = (__m128i)_mm_shuffle_pd((__m128d)temp1,(__m128d)temp3,1); + temp2=_mm_aeskeygenassist_si128 (temp3,0x2); + KEY_192_ASSIST(&temp1, &temp2, &temp3); + Key_Schedule[3]=temp1; + Key_Schedule[4]=temp3; + temp2=_mm_aeskeygenassist_si128 (temp3,0x4); + KEY_192_ASSIST(&temp1, &temp2, &temp3); + Key_Schedule[4] = (__m128i)_mm_shuffle_pd((__m128d)Key_Schedule[4], (__m128d)temp1,0); + Key_Schedule[5] = (__m128i)_mm_shuffle_pd((__m128d)temp1,(__m128d)temp3,1); + temp2=_mm_aeskeygenassist_si128 (temp3,0x8); + KEY_192_ASSIST(&temp1, &temp2, &temp3); + Key_Schedule[6]=temp1; + Key_Schedule[7]=temp3; + temp2=_mm_aeskeygenassist_si128 (temp3,0x10); + KEY_192_ASSIST(&temp1, &temp2, &temp3); + Key_Schedule[7] = (__m128i)_mm_shuffle_pd((__m128d)Key_Schedule[7], (__m128d)temp1,0); + Key_Schedule[8] = (__m128i)_mm_shuffle_pd((__m128d)temp1,(__m128d)temp3,1); + temp2=_mm_aeskeygenassist_si128 (temp3,0x20); + KEY_192_ASSIST(&temp1, &temp2, &temp3); + Key_Schedule[9]=temp1; + Key_Schedule[10]=temp3; + temp2=_mm_aeskeygenassist_si128 (temp3,0x40); + KEY_192_ASSIST(&temp1, &temp2, &temp3); + Key_Schedule[10] = (__m128i)_mm_shuffle_pd((__m128d)Key_Schedule[10], (__m128d)temp1,0); + Key_Schedule[11] = (__m128i)_mm_shuffle_pd((__m128d)temp1,(__m128d)temp3,1); + temp2=_mm_aeskeygenassist_si128 (temp3,0x80); + KEY_192_ASSIST(&temp1, &temp2, &temp3); + Key_Schedule[12]=temp1; +} + +inline void KEY_256_ASSIST_1(__m128i* temp1, __m128i * temp2) +{ + __m128i temp4; + *temp2 = _mm_shuffle_epi32(*temp2, 0xff); + temp4 = _mm_slli_si128 (*temp1, 0x4); + *temp1 = _mm_xor_si128 (*temp1, temp4); + temp4 = _mm_slli_si128 (temp4, 0x4); + *temp1 = _mm_xor_si128 (*temp1, temp4); + temp4 = _mm_slli_si128 (temp4, 0x4); + *temp1 = _mm_xor_si128 (*temp1, temp4); + *temp1 = _mm_xor_si128 (*temp1, *temp2); +} + +inline void KEY_256_ASSIST_2(__m128i* temp1, __m128i * temp3) +{ + __m128i temp2,temp4; + temp4 = _mm_aeskeygenassist_si128 (*temp1, 0x0); + temp2 = _mm_shuffle_epi32(temp4, 0xaa); + temp4 = _mm_slli_si128 (*temp3, 0x4); + *temp3 = _mm_xor_si128 (*temp3, temp4); + temp4 = _mm_slli_si128 (temp4, 0x4); + *temp3 = _mm_xor_si128 (*temp3, temp4); + temp4 = _mm_slli_si128 (temp4, 0x4); + *temp3 = _mm_xor_si128 (*temp3, temp4); + *temp3 = _mm_xor_si128 (*temp3, temp2); +} + +void AES_256_Key_Expansion (const unsigned char *userkey, unsigned char *key) +{ + __m128i temp1, temp2, temp3; + __m128i *Key_Schedule = (__m128i*)key; + temp1 = _mm_loadu_si128((__m128i*)userkey); + temp3 = _mm_loadu_si128((__m128i*)(userkey+16)); + Key_Schedule[0] = temp1; Key_Schedule[1] = temp3; + temp2 = _mm_aeskeygenassist_si128 (temp3,0x01); + KEY_256_ASSIST_1(&temp1, &temp2); + Key_Schedule[2]=temp1; + KEY_256_ASSIST_2(&temp1, &temp3); + Key_Schedule[3]=temp3; + temp2 = _mm_aeskeygenassist_si128 (temp3,0x02); + KEY_256_ASSIST_1(&temp1, &temp2); + Key_Schedule[4]=temp1; + KEY_256_ASSIST_2(&temp1, &temp3); + Key_Schedule[5]=temp3; + temp2 = _mm_aeskeygenassist_si128 (temp3,0x04); + KEY_256_ASSIST_1(&temp1, &temp2); + Key_Schedule[6]=temp1; + KEY_256_ASSIST_2(&temp1, &temp3); + Key_Schedule[7]=temp3; + temp2 = _mm_aeskeygenassist_si128 (temp3,0x08); + KEY_256_ASSIST_1(&temp1, &temp2); + Key_Schedule[8]=temp1; + KEY_256_ASSIST_2(&temp1, &temp3); + Key_Schedule[9]=temp3; + temp2 = _mm_aeskeygenassist_si128 (temp3,0x10); + KEY_256_ASSIST_1(&temp1, &temp2); + Key_Schedule[10]=temp1; + KEY_256_ASSIST_2(&temp1, &temp3); + Key_Schedule[11]=temp3; + temp2 = _mm_aeskeygenassist_si128 (temp3,0x20); + KEY_256_ASSIST_1(&temp1, &temp2); + Key_Schedule[12]=temp1; + KEY_256_ASSIST_2(&temp1, &temp3); + Key_Schedule[13]=temp3; + temp2 = _mm_aeskeygenassist_si128 (temp3,0x40); + KEY_256_ASSIST_1(&temp1, &temp2); + Key_Schedule[14]=temp1; +} +#ifdef __cplusplus +} +#endif diff --git a/main.cpp b/main.cpp index 40e661c..ef3b7c2 100644 --- a/main.cpp +++ b/main.cpp @@ -1,11 +1,13 @@ #include #include + +#ifdef __cplusplus #include "unit_test/aestest.h" +#endif int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); - AesTest test1; QTest::qExec(&test1); return 0; diff --git a/qaesencryption.cpp b/qaesencryption.cpp index 3566862..6461dd1 100644 --- a/qaesencryption.cpp +++ b/qaesencryption.cpp @@ -1,4 +1,12 @@ #include "qaesencryption.h" +#include +#include + +#ifdef USE_INTEL_AES_IF_AVAILABLE +#include "aesni/aesni-key-exp.c" +#include "aesni/aesni-enc-ecb.c" +#include "aesni/aesni-enc-cbc.c" +#endif /* * Static Functions @@ -90,9 +98,14 @@ inline quint8 multiply(quint8 x, quint8 y){ QAESEncryption::QAESEncryption(Aes level, Mode mode, Padding padding) : m_nb(4), m_blocklen(16), m_level(level), m_mode(mode), m_padding(padding) + , m_aesNIAvailable(false) { m_state = NULL; +#ifdef USE_INTEL_AES_IF_AVAILABLE + m_aesNIAvailable = check_aesni_support(); +#endif + switch (level) { case AES_128: { @@ -156,56 +169,99 @@ QByteArray QAESEncryption::getPadding(int currSize, int alignment) QByteArray QAESEncryption::expandKey(const QByteArray &key) { - int i, k; - quint8 tempa[4]; // Used for the column/row operations - QByteArray roundKey(key); - // The first round key is the key itself. - // ... +#ifdef USE_INTEL_AES_IF_AVAILABLE + if (true){ + switch(m_level) { + case AES_128: { + AES128 aes128; + quint8 ret[aes128.expandedKey]; + memset(ret, 0x00, sizeof(ret)); + quint8 uchar_key[key.size()]; + memcpy(uchar_key, key.data(), key.size()); + AES_128_Key_Expansion(uchar_key, ret); + return QByteArray((char*) ret, aes128.expandedKey); + } + break; + case AES_192: { + AES192 aes192; + quint8 ret[aes192.expandedKey]; + memset(ret, 0x00, sizeof(ret)); + quint8 uchar_key[key.size()]; + memcpy(uchar_key, key.data(), key.size()); - // All other round keys are found from the previous round keys. - //i == Nk - for(i = m_nk; i < m_nb * (m_nr + 1); i++) + AES_192_Key_Expansion(uchar_key, ret); + return QByteArray((char*) ret, aes192.expandedKey); + } + break; + case AES_256: { + AES256 aes256; + quint8 ret[aes256.expandedKey]; + memset(ret, 0x00, sizeof(ret)); + quint8 uchar_key[key.size()]; + memcpy(uchar_key, key.data(), key.size()); + + AES_256_Key_Expansion(uchar_key, ret); + return QByteArray((char*) ret, aes256.expandedKey); + } + break; + default: + return QByteArray(); + break; + } + } else +#endif { - tempa[0] = (quint8) roundKey.at((i-1) * 4 + 0); - tempa[1] = (quint8) roundKey.at((i-1) * 4 + 1); - tempa[2] = (quint8) roundKey.at((i-1) * 4 + 2); - tempa[3] = (quint8) roundKey.at((i-1) * 4 + 3); - if (i % m_nk == 0) - { - // This function shifts the 4 bytes in a word to the left once. - // [a0,a1,a2,a3] becomes [a1,a2,a3,a0] + int i, k; + quint8 tempa[4]; // Used for the column/row operations + QByteArray roundKey(key); // The first round key is the key itself. - // Function RotWord() - k = tempa[0]; - tempa[0] = tempa[1]; - tempa[1] = tempa[2]; - tempa[2] = tempa[3]; - tempa[3] = k; + // All other round keys are found from the previous round keys. + //i == Nk + for(i = m_nk; i < m_nb * (m_nr + 1); i++) + { + tempa[0] = (quint8) roundKey.at((i-1) * 4 + 0); + tempa[1] = (quint8) roundKey.at((i-1) * 4 + 1); + tempa[2] = (quint8) roundKey.at((i-1) * 4 + 2); + tempa[3] = (quint8) roundKey.at((i-1) * 4 + 3); - // Function Subword() - tempa[0] = getSBoxValue(tempa[0]); - tempa[1] = getSBoxValue(tempa[1]); - tempa[2] = getSBoxValue(tempa[2]); - tempa[3] = getSBoxValue(tempa[3]); + if (i % m_nk == 0) + { + // This function shifts the 4 bytes in a word to the left once. + // [a0,a1,a2,a3] becomes [a1,a2,a3,a0] - tempa[0] = tempa[0] ^ Rcon[i/m_nk]; - } - if (m_level == AES_256 && i % m_nk == 4) - { - // Function Subword() - tempa[0] = getSBoxValue(tempa[0]); - tempa[1] = getSBoxValue(tempa[1]); - tempa[2] = getSBoxValue(tempa[2]); - tempa[3] = getSBoxValue(tempa[3]); - } - roundKey.insert(i * 4 + 0, (quint8) roundKey.at((i - m_nk) * 4 + 0) ^ tempa[0]); - roundKey.insert(i * 4 + 1, (quint8) roundKey.at((i - m_nk) * 4 + 1) ^ tempa[1]); - roundKey.insert(i * 4 + 2, (quint8) roundKey.at((i - m_nk) * 4 + 2) ^ tempa[2]); - roundKey.insert(i * 4 + 3, (quint8) roundKey.at((i - m_nk) * 4 + 3) ^ tempa[3]); + // Function RotWord() + k = tempa[0]; + tempa[0] = tempa[1]; + tempa[1] = tempa[2]; + tempa[2] = tempa[3]; + tempa[3] = k; + + // Function Subword() + tempa[0] = getSBoxValue(tempa[0]); + tempa[1] = getSBoxValue(tempa[1]); + tempa[2] = getSBoxValue(tempa[2]); + tempa[3] = getSBoxValue(tempa[3]); + + tempa[0] = tempa[0] ^ Rcon[i/m_nk]; + } + + if (m_level == AES_256 && i % m_nk == 4) + { + // Function Subword() + tempa[0] = getSBoxValue(tempa[0]); + tempa[1] = getSBoxValue(tempa[1]); + tempa[2] = getSBoxValue(tempa[2]); + tempa[3] = getSBoxValue(tempa[3]); + } + roundKey.insert(i * 4 + 0, (quint8) roundKey.at((i - m_nk) * 4 + 0) ^ tempa[0]); + roundKey.insert(i * 4 + 1, (quint8) roundKey.at((i - m_nk) * 4 + 1) ^ tempa[1]); + roundKey.insert(i * 4 + 2, (quint8) roundKey.at((i - m_nk) * 4 + 2) ^ tempa[2]); + roundKey.insert(i * 4 + 3, (quint8) roundKey.at((i - m_nk) * 4 + 3) ^ tempa[3]); + } + return roundKey; } - return roundKey; } // This function adds the round key to state. @@ -413,12 +469,20 @@ QByteArray QAESEncryption::invCipher(const QByteArray &expKey, const QByteArray return output; } +QByteArray QAESEncryption::printArray(uchar* arr, int size) +{ + QByteArray print(""); + for(int i=0; i= CBC && (iv.isNull() || iv.size() != m_blocklen)) return QByteArray(); - QByteArray ret; QByteArray expandedKey = expandKey(key); QByteArray alignedText(rawText); @@ -427,40 +491,81 @@ QByteArray QAESEncryption::encode(const QByteArray &rawText, const QByteArray &k switch(m_mode) { - case ECB: + case ECB: { +#ifdef USE_INTEL_AES_IF_AVAILABLE + if (m_aesNIAvailable){ + unsigned char in[alignedText.size()]; + memcpy(in, alignedText.data(), alignedText.size()); + unsigned char out[alignedText.size()]; + memcpy(out, alignedText.data(), alignedText.size()); + char expKey[expandedKey.size()]; + memcpy(expKey, expandedKey.data(), expandedKey.size()); + AES_ECB_encrypt(in, out, alignedText.size(), + expKey, m_nr); + return QByteArray((char*)out, alignedText.size()); + } +#endif + QByteArray ret; for(int i=0; i < alignedText.size(); i+= m_blocklen) ret.append(cipher(expandedKey, alignedText.mid(i, m_blocklen))); - break; + return ret; + } + break; case CBC: { - QByteArray ivTemp(iv); - for(int i=0; i < alignedText.size(); i+= m_blocklen) { - alignedText.replace(i, m_blocklen, byteXor(alignedText.mid(i, m_blocklen),ivTemp)); - ret.append(cipher(expandedKey, alignedText.mid(i, m_blocklen))); - ivTemp = ret.mid(i, m_blocklen); - } +#ifdef USE_INTEL_AES_IF_AVAILABLE + if (m_aesNIAvailable){ + quint8 in[alignedText.size()]; + memcpy(in, alignedText.constData(), alignedText.size()); + quint8 ivec[iv.size()]; + memcpy(ivec, iv.data(), iv.size()); + char out[alignedText.size()]; + memset(out, 0x00, alignedText.size()); + char expKey[expandedKey.size()]; + memcpy(expKey, expandedKey.data(), expandedKey.size()); + AES_CBC_encrypt(in, + (unsigned char*) out, + ivec, + alignedText.size(), + expKey, + m_nr); + return QByteArray(out, alignedText.size()); } - break; +#endif + QByteArray ret; + QByteArray ivTemp(iv); + for(int i=0; i < alignedText.size(); i+= m_blocklen) { + alignedText.replace(i, m_blocklen, byteXor(alignedText.mid(i, m_blocklen),ivTemp)); + ret.append(cipher(expandedKey, alignedText.mid(i, m_blocklen))); + ivTemp = ret.mid(i, m_blocklen); + } + return ret; + } + break; case CFB: { - ret.append(byteXor(alignedText.left(m_blocklen), cipher(expandedKey, iv))); - for(int i=0; i < alignedText.size(); i+= m_blocklen) { - if (i+m_blocklen < alignedText.size()) - ret.append(byteXor(alignedText.mid(i+m_blocklen, m_blocklen), - cipher(expandedKey, ret.mid(i, m_blocklen)))); - } + QByteArray ret; + ret.append(byteXor(alignedText.left(m_blocklen), cipher(expandedKey, iv))); + for(int i=0; i < alignedText.size(); i+= m_blocklen) { + if (i+m_blocklen < alignedText.size()) + ret.append(byteXor(alignedText.mid(i+m_blocklen, m_blocklen), + cipher(expandedKey, ret.mid(i, m_blocklen)))); } - break; + return ret; + } + break; case OFB: { - QByteArray ofbTemp; - ofbTemp.append(cipher(expandedKey, iv)); - for (int i=m_blocklen; i < alignedText.size(); i += m_blocklen){ - ofbTemp.append(cipher(expandedKey, ofbTemp.right(m_blocklen))); - } - ret.append(byteXor(alignedText, ofbTemp)); + QByteArray ret; + QByteArray ofbTemp; + ofbTemp.append(cipher(expandedKey, iv)); + for (int i=m_blocklen; i < alignedText.size(); i += m_blocklen){ + ofbTemp.append(cipher(expandedKey, ofbTemp.right(m_blocklen))); } - break; + ret.append(byteXor(alignedText, ofbTemp)); + return ret; + } + break; default: break; } - return ret; + return QByteArray(); } QByteArray QAESEncryption::decode(const QByteArray &rawText, const QByteArray &key, const QByteArray &iv) diff --git a/qaesencryption.h b/qaesencryption.h index 90e54bd..4f3165e 100644 --- a/qaesencryption.h +++ b/qaesencryption.h @@ -4,6 +4,12 @@ #include #include +#ifdef __linux__ +#ifndef __LP64__ +#define do_rdtsc _do_rdtsc +#endif +#endif + class QAESEncryption : public QObject { Q_OBJECT @@ -42,6 +48,7 @@ public: QByteArray removePadding(const QByteArray &rawText); QByteArray expandKey(const QByteArray &key); + QByteArray printArray(uchar *arr, int size); signals: public slots: @@ -56,6 +63,7 @@ private: int m_nr; int m_expandedKey; int m_padding; + bool m_aesNIAvailable; QByteArray* m_state; struct AES256{ diff --git a/qaesencryption.pro b/qaesencryption.pro index 1e728c1..d5d2ed1 100644 --- a/qaesencryption.pro +++ b/qaesencryption.pro @@ -9,16 +9,15 @@ CONFIG -= app_bundle TEMPLATE = app -SOURCES += main.cpp \ - qaesencryption.cpp \ - unit_test/aestest.cpp - # The following define makes your compiler emit warnings if you use # any feature of Qt which as been marked deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. DEFINES += QT_DEPRECATED_WARNINGS +DEFINES += USE_INTEL_AES_IF_AVAILABLE +QMAKE_CXXFLAGS += -maes + # You can also make your code fail to compile if you use deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. @@ -26,7 +25,14 @@ DEFINES += QT_DEPRECATED_WARNINGS HEADERS += \ qaesencryption.h \ - unit_test/aestest.h + unit_test/aestest.h \ + +SOURCES += main.cpp \ + qaesencryption.cpp \ + unit_test/aestest.cpp \ + aesni/aesni-key-exp.c \ + aesni/aesni-enc-ecb.c \ + aesni/aesni-enc-cbc.c DISTFILES += \ unit_test/longText.txt diff --git a/unit_test/aestest.cpp b/unit_test/aestest.cpp index 39080ca..e083e00 100644 --- a/unit_test/aestest.cpp +++ b/unit_test/aestest.cpp @@ -8,6 +8,9 @@ void AesTest::initTestCase() { +#ifdef USE_INTEL_AES_IF_AVAILABLE + qDebug() << "AESNI Enabled"; +#endif quint8 key_16[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}; for (int i=0; i<16; i++) key16.append(key_16[i]); @@ -54,6 +57,7 @@ void AesTest::initTestCase() inCBC128.append(text_cbc[i]); outCBC128.append(output_cbc[i]); } + }