Skip to content

Commit 3350cf1

Browse files
authored
Merge pull request #1 from bricke/CFB-mode
CFB mode
2 parents 8470ae1 + 666e9dd commit 3350cf1

File tree

5 files changed

+77
-23
lines changed

5 files changed

+77
-23
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Qt-AES
22
Small and portable AES encryption class for Qt.
3-
Supports all key sizes - 128/192/256 bits - ECB and CBC modes
3+
Supports all key sizes - 128/192/256 bits - ECB, CBC and CFB modes
44

55
## Usage
66

qaesencryption.cpp

Lines changed: 53 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -273,14 +273,14 @@ void QAESEncryption::invShiftRows()
273273
it[11] = (quint8)temp;
274274
}
275275

276-
QByteArray QAESEncryption::ivXor(const QByteArray in, const QByteArray iv)
276+
QByteArray QAESEncryption::byteXor(const QByteArray a, const QByteArray b)
277277
{
278-
QByteArray::const_iterator it = in.begin();
279-
QByteArray::const_iterator it_iv = iv.begin();
278+
QByteArray::const_iterator it_a = a.begin();
279+
QByteArray::const_iterator it_b = b.begin();
280280
QByteArray ret;
281281

282282
for(int i = 0; i < m_blocklen; i++)
283-
ret.insert(i,it[i] ^ it_iv[i]);
283+
ret.insert(i,it_a[i] ^ it_b[i]);
284284

285285
return ret;
286286
}
@@ -345,45 +345,78 @@ QByteArray QAESEncryption::invCipher(const QByteArray expKey, const QByteArray i
345345

346346
QByteArray QAESEncryption::encode(const QByteArray rawText, const QByteArray key, const QByteArray iv)
347347
{
348-
if (m_mode == CBC && (iv.isNull() || iv.size() != m_blocklen))
348+
if (m_mode >= CBC && (iv.isNull() || iv.size() != m_blocklen))
349349
return QByteArray();
350350

351351
QByteArray ret;
352352
QByteArray expandedKey = expandKey(key);
353353
QByteArray alignedText(rawText);
354354
QByteArray ivTemp(iv);
355355

356-
357356
alignedText.append(getPadding(rawText.size(), m_blocklen), 0); //filling the array with zeros
358357

359-
for(int i=0; i < alignedText.size(); i+= m_blocklen){
360-
if (m_mode == CBC)
361-
alignedText.replace(i, m_blocklen, ivXor(alignedText.mid(i, m_blocklen),ivTemp));
362-
363-
ret.append(cipher(expandedKey, alignedText.mid(i, m_blocklen)));
358+
//Preparation for CFB
359+
if (m_mode == CFB)
360+
ret.append(byteXor(alignedText.mid(0, m_blocklen), cipher(expandedKey, iv)));
364361

365-
if (m_mode == CBC)
362+
//Looping thru all blocks
363+
for(int i=0; i < alignedText.size(); i+= m_blocklen){
364+
switch(m_mode)
365+
{
366+
case ECB:
367+
ret.append(cipher(expandedKey, alignedText.mid(i, m_blocklen)));
368+
break;
369+
case CBC:
370+
alignedText.replace(i, m_blocklen, byteXor(alignedText.mid(i, m_blocklen),ivTemp));
371+
ret.append(cipher(expandedKey, alignedText.mid(i, m_blocklen)));
366372
ivTemp = ret.mid(i, m_blocklen);
373+
break;
374+
case CFB:
375+
if (i+m_blocklen < alignedText.size())
376+
ret.append(byteXor(alignedText.mid(i+m_blocklen, m_blocklen),
377+
cipher(expandedKey, ret.mid(i, m_blocklen))));
378+
break;
379+
default:
380+
//do nothing
381+
break;
382+
}
367383
}
368384
return ret;
369385
}
370386

371387
QByteArray QAESEncryption::decode(const QByteArray rawText, const QByteArray key, const QByteArray iv)
372388
{
373-
if (m_mode == CBC && (iv.isNull() || iv.size() != m_blocklen))
389+
if (m_mode >= CBC && (iv.isNull() || iv.size() != m_blocklen))
374390
return QByteArray();
375391

376392
QByteArray ret;
377393
QByteArray expandedKey = expandKey(key);
378-
QByteArray alignedText(rawText);
379394
QByteArray ivTemp(iv);
380395

381-
for(int i=0; i < alignedText.size(); i+= m_blocklen){
382-
ret.append(invCipher(expandedKey, alignedText.mid(i, m_blocklen)));
383-
384-
if (m_mode == CBC) {
385-
ret.replace(i, m_blocklen, ivXor(ret.mid(i, m_blocklen),ivTemp));
386-
ivTemp = alignedText.mid(i, m_blocklen);
396+
//Preparation for CFB
397+
if (m_mode == CFB)
398+
ret.append(byteXor(rawText.mid(0, m_blocklen), cipher(expandedKey, iv)));
399+
400+
for(int i=0; i < rawText.size(); i+= m_blocklen){
401+
switch(m_mode)
402+
{
403+
case ECB:
404+
ret.append(invCipher(expandedKey, rawText.mid(i, m_blocklen)));
405+
break;
406+
case CBC:
407+
ret.append(invCipher(expandedKey, rawText.mid(i, m_blocklen)));
408+
ret.replace(i, m_blocklen, byteXor(ret.mid(i, m_blocklen),ivTemp));
409+
ivTemp = rawText.mid(i, m_blocklen);
410+
break;
411+
case CFB:
412+
if (i+m_blocklen < rawText.size()){
413+
ret.append(byteXor(rawText.mid(i+m_blocklen, m_blocklen),
414+
cipher(expandedKey, rawText.mid(i, m_blocklen))));
415+
}
416+
break;
417+
default:
418+
//do nothing
419+
break;
387420
}
388421
}
389422
return ret;

qaesencryption.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ class QAESEncryption : public QObject
1616

1717
typedef enum {
1818
ECB,
19-
CBC
19+
CBC,
20+
CFB
2021
} MODE;
2122

2223
static QByteArray Crypt(QAESEncryption::AES level, QAESEncryption::MODE mode, const QByteArray rawText, const QByteArray key, const QByteArray iv = NULL);
@@ -77,7 +78,7 @@ public slots:
7778
void invShiftRows();
7879
QByteArray cipher(const QByteArray expKey, const QByteArray plainText);
7980
QByteArray invCipher(const QByteArray expKey, const QByteArray plainText);
80-
QByteArray ivXor(const QByteArray in, const QByteArray iv);
81+
QByteArray byteXor(const QByteArray in, const QByteArray iv);
8182

8283
const quint8 sbox[256] = {
8384
//0 1 2 3 4 5 6 7 8 9 A B C D E F

unit_test/aestest.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,3 +133,21 @@ void AesTest::CBC128Decrypt()
133133

134134
QCOMPARE(encryption.decode(outCBC128, key16, iv), inCBC128);
135135
}
136+
137+
//=================== CFB TESTING ============================
138+
139+
void AesTest::CFB256String()
140+
{
141+
QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::CFB);
142+
143+
QString inputStr("The Advanced Encryption Standard (AES), also known by its original name Rijndael "
144+
"is a specification for the encryption of electronic data established by the U.S. "
145+
"National Institute of Standards and Technology (NIST) in 2001");
146+
QString key("123456789123");
147+
148+
QByteArray hashKey = QCryptographicHash::hash(key.toLocal8Bit(), QCryptographicHash::Sha256);
149+
150+
QByteArray encodeText = encryption.encode(inputStr.toLocal8Bit(), hashKey, iv);
151+
152+
QCOMPARE(QString(encryption.decode(encodeText, hashKey, iv)), inputStr);
153+
}

unit_test/aestest.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ private slots:
2525
void CBC128Crypt();
2626
void CBC128Decrypt();
2727

28+
void CFB256String();
29+
2830
void cleanupTestCase(){}
2931

3032
private:

0 commit comments

Comments
 (0)