From 4ce12493f6e32c6c8fb8396c843b05e7b327facc Mon Sep 17 00:00:00 2001 From: Matteo Brichese <mbrichese@ics.com> Date: Tue, 3 Apr 2018 17:42:03 -0700 Subject: [PATCH 1/2] first try on OFB - not tested --- qaesencryption.cpp | 14 +++++++++++++- qaesencryption.h | 7 ++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/qaesencryption.cpp b/qaesencryption.cpp index 4001dfe..a21e087 100644 --- a/qaesencryption.cpp +++ b/qaesencryption.cpp @@ -398,13 +398,16 @@ QByteArray QAESEncryption::encode(const QByteArray &rawText, const QByteArray &k QByteArray expandedKey = expandKey(key); QByteArray alignedText(rawText); QByteArray ivTemp(iv); + QByteArray ofbTemp; //Fill array with padding alignedText.append(getPadding(rawText.size(), m_blocklen)); //Preparation for CFB - if (m_mode == CFB) + if (m_mode == CFB || m_mode == OFB) ret.append(byteXor(alignedText.mid(0, m_blocklen), cipher(expandedKey, iv))); + if (m_mode == OFB) + ofbTemp.append(cipher(expandedKey, iv)); //Looping thru all blocks for(int i=0; i < alignedText.size(); i+= m_blocklen){ @@ -423,6 +426,15 @@ QByteArray QAESEncryption::encode(const QByteArray &rawText, const QByteArray &k ret.append(byteXor(alignedText.mid(i+m_blocklen, m_blocklen), cipher(expandedKey, ret.mid(i, m_blocklen)))); break; + case OFB: + if (i+m_blocklen < alignedText.size()) + { + ret.append(byteXor(alignedText.mid(i+m_blocklen, m_blocklen), + cipher(expandedKey, ofbTemp.mid(i-m_blocklen, m_blocklen)))); + ofbTemp.append(cipher(expandedKey, ofbTemp.mid(i-m_blocklen, m_blocklen))); + } + + break; default: //do nothing break; diff --git a/qaesencryption.h b/qaesencryption.h index 9717812..5c34557 100644 --- a/qaesencryption.h +++ b/qaesencryption.h @@ -17,7 +17,8 @@ public: enum Mode { ECB, CBC, - CFB + CFB, + OFB }; enum Padding { @@ -132,9 +133,9 @@ private: // The round constant word array, Rcon[i], contains the values given by // x to th e power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8) - //Only the first 14 elements are needed + // Only the first 14 elements are needed const quint8 Rcon[256] = { - 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, /*0x4d, 0x9a, + 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab/*, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, From 278565d6610136e277414c32dc705cc5a89f1583 Mon Sep 17 00:00:00 2001 From: Matteo Brichese <mbrichese@ics.com> Date: Thu, 5 Apr 2018 16:07:22 -0700 Subject: [PATCH 2/2] adding OFB with basic test --- qaesencryption.cpp | 126 ++++++++++++++++++++++-------------------- unit_test/aestest.cpp | 19 ++++++- unit_test/aestest.h | 2 + 3 files changed, 87 insertions(+), 60 deletions(-) diff --git a/qaesencryption.cpp b/qaesencryption.cpp index a21e087..ac240fc 100644 --- a/qaesencryption.cpp +++ b/qaesencryption.cpp @@ -325,7 +325,8 @@ QByteArray QAESEncryption::byteXor(const QByteArray &a, const QByteArray &b) QByteArray::const_iterator it_b = b.begin(); QByteArray ret; - for(int i = 0; i < m_blocklen; i++) + //for(int i = 0; i < m_blocklen; i++) + for(int i = 0; i < std::min(a.size(), b.size()); i++) ret.insert(i,it_a[i] ^ it_b[i]); return ret; @@ -397,48 +398,44 @@ QByteArray QAESEncryption::encode(const QByteArray &rawText, const QByteArray &k QByteArray ret; QByteArray expandedKey = expandKey(key); QByteArray alignedText(rawText); - QByteArray ivTemp(iv); - QByteArray ofbTemp; //Fill array with padding alignedText.append(getPadding(rawText.size(), m_blocklen)); - //Preparation for CFB - if (m_mode == CFB || m_mode == OFB) - ret.append(byteXor(alignedText.mid(0, m_blocklen), cipher(expandedKey, iv))); - if (m_mode == OFB) - ofbTemp.append(cipher(expandedKey, iv)); - - //Looping thru all blocks - for(int i=0; i < alignedText.size(); i+= m_blocklen){ - switch(m_mode) - { - case ECB: + switch(m_mode) + { + case ECB: + for(int i=0; i < alignedText.size(); i+= m_blocklen) ret.append(cipher(expandedKey, alignedText.mid(i, m_blocklen))); - break; - case CBC: - 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); - break; - case CFB: - if (i+m_blocklen < alignedText.size()) - ret.append(byteXor(alignedText.mid(i+m_blocklen, m_blocklen), - cipher(expandedKey, ret.mid(i, m_blocklen)))); - break; - case OFB: - if (i+m_blocklen < alignedText.size()) - { - ret.append(byteXor(alignedText.mid(i+m_blocklen, m_blocklen), - cipher(expandedKey, ofbTemp.mid(i-m_blocklen, m_blocklen)))); - ofbTemp.append(cipher(expandedKey, ofbTemp.mid(i-m_blocklen, m_blocklen))); + 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); } - - break; - default: - //do nothing - break; } + 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)))); + } + } + 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)); + } + break; + default: break; } return ret; } @@ -450,33 +447,44 @@ QByteArray QAESEncryption::decode(const QByteArray &rawText, const QByteArray &k QByteArray ret; QByteArray expandedKey = expandKey(key); - QByteArray ivTemp(iv); - //Preparation for CFB - if (m_mode == CFB) - ret.append(byteXor(rawText.mid(0, m_blocklen), cipher(expandedKey, iv))); - - for(int i=0; i < rawText.size(); i+= m_blocklen){ - switch(m_mode) - { - case ECB: + switch(m_mode) + { + case ECB: + for(int i=0; i < rawText.size(); i+= m_blocklen) ret.append(invCipher(expandedKey, rawText.mid(i, m_blocklen))); - break; - case CBC: - ret.append(invCipher(expandedKey, rawText.mid(i, m_blocklen))); - ret.replace(i, m_blocklen, byteXor(ret.mid(i, m_blocklen),ivTemp)); - ivTemp = rawText.mid(i, m_blocklen); - break; - case CFB: - if (i+m_blocklen < rawText.size()){ - ret.append(byteXor(rawText.mid(i+m_blocklen, m_blocklen), - cipher(expandedKey, rawText.mid(i, m_blocklen)))); + break; + case CBC: { + QByteArray ivTemp(iv); + for(int i=0; i < rawText.size(); i+= m_blocklen){ + ret.append(invCipher(expandedKey, rawText.mid(i, m_blocklen))); + ret.replace(i, m_blocklen, byteXor(ret.mid(i, m_blocklen),ivTemp)); + ivTemp = rawText.mid(i, m_blocklen); } - break; - default: - //do nothing - break; } + break; + case CFB: { + ret.append(byteXor(rawText.mid(0, m_blocklen), cipher(expandedKey, iv))); + for(int i=0; i < rawText.size(); i+= m_blocklen){ + if (i+m_blocklen < rawText.size()) { + ret.append(byteXor(rawText.mid(i+m_blocklen, m_blocklen), + cipher(expandedKey, rawText.mid(i, m_blocklen)))); + } + } + } + break; + case OFB: { + QByteArray ofbTemp; + ofbTemp.append(cipher(expandedKey, iv)); + for (int i=m_blocklen; i < rawText.size(); i += m_blocklen){ + ofbTemp.append(cipher(expandedKey, ofbTemp.right(m_blocklen))); + } + ret.append(byteXor(rawText, ofbTemp)); + } + break; + default: + //do nothing + break; } return ret; } diff --git a/unit_test/aestest.cpp b/unit_test/aestest.cpp index 0119b1a..25ab728 100644 --- a/unit_test/aestest.cpp +++ b/unit_test/aestest.cpp @@ -1,5 +1,6 @@ #include "aestest.h" +#include <QDebug> #include <QByteArray> #include <QCryptographicHash> #include <QFile> @@ -139,7 +140,7 @@ void AesTest::CBC128Decrypt() void AesTest::CFB256String() { - QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::CFB); + QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::CFB, QAESEncryption::PKCS7); QString inputStr("The Advanced Encryption Standard (AES), also known by its original name Rijndael " "is a specification for the encryption of electronic data established by the U.S. " @@ -171,3 +172,19 @@ void AesTest::CFB256LongText() QByteArray decodedText = encryption.removePadding(encryption.decode(encodeText, hashKey, iv)); QCOMPARE(decodedText, input); } + +void AesTest::OFB256String() +{ + QAESEncryption encryption(QAESEncryption::AES_128, QAESEncryption::OFB, QAESEncryption::PKCS7); + + QString inputStr("The Advanced Encryption Standard (AES), also known by its original name Rijndael " + "is a specification for the encryption of electronic data established by the U.S. " + "National Institute of Standards and Technology (NIST) in 2001"); + QString key("123456789123"); + + QByteArray hashKey = QCryptographicHash::hash(key.toLocal8Bit(), QCryptographicHash::Sha256); + QByteArray encodeText = encryption.encode(inputStr.toLocal8Bit(), hashKey, iv); + + QByteArray decodedText = encryption.removePadding(encryption.decode(encodeText, hashKey, iv)); + QCOMPARE(inputStr, decodedText); +} diff --git a/unit_test/aestest.h b/unit_test/aestest.h index bd6c03e..eeaa5fc 100644 --- a/unit_test/aestest.h +++ b/unit_test/aestest.h @@ -29,6 +29,8 @@ private slots: void CFB256LongText(); + void OFB256String(); + void cleanupTestCase(){} private: