Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PCBC implementation + incrBytes() for C-PCBC implementation #49

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# C++ objects and libs
*.slo
*.lo
*.o
*.a
*.la
*.lai
*.so
*.so.*
*.dll
*.dylib

# Qt-es
object_script.*.Release
object_script.*.Debug
*_plugin_import.cpp
/.qmake.cache
/.qmake.stash
*.pro.user
*.pro.user.*
*.qbs.user
*.qbs.user.*
*.moc
moc_*.cpp
moc_*.h
qrc_*.cpp
ui_*.h
*.qmlc
*.jsc
Makefile*
*build-*
*.qm
*.prl

# Qt unit tests
target_wrapper.*

# QtCreator
*.autosave

# QtCreator Qml
*.qmlproject.user
*.qmlproject.user.*

# QtCreator CMake
CMakeLists.txt.user*

# QtCreator 4.8< compilation database
compile_commands.json

# QtCreator local machine specific files for imported projects
*creator.user*

*_qmlcache.qrc
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ The class supports the following operating modes

* ECB
* CBC
* CCBC
* PCBC
* CPCBC
* CFB
* OFB

Expand Down
116 changes: 103 additions & 13 deletions qaesencryption.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,23 @@ QByteArray QAESEncryption::byteXor(const QByteArray &a, const QByteArray &b)
return ret;
}

// Treats this as a (this->length()) bytes number to increment it.
QByteArray QAESEncryption::incrBytes(const QByteArray &bytes, const quint8 &inc, const quint64 &count){
QByteArray ret = bytes;
for(quint64 i = 0; i< count; i++){
unsigned char *lsb = (unsigned char *)(ret.data() + (ret.length()-1));
quint8 inc_ = inc;
for(quint8 diff = 0xFF - *lsb; inc_ > 0; lsb--, diff = 0xFF - *lsb){
if(inc_ <= diff){
*lsb += inc_, inc_ = 0;
}else{
inc_ -= diff, *lsb = 0;
}
}
}
return ret;
}

// Cipher is the main function that encrypts the PlainText.
QByteArray QAESEncryption::cipher(const QByteArray &expKey, const QByteArray &in)
{
Expand Down Expand Up @@ -481,11 +498,10 @@ QByteArray QAESEncryption::printArray(uchar* arr, int size)
return print.toHex();
}

QByteArray QAESEncryption::encode(const QByteArray &rawText, const QByteArray &key, const QByteArray &iv)
QByteArray QAESEncryption::encode(const QByteArray &rawText, const QByteArray &key, const QByteArray &iv1, const QByteArray &iv2, const quint8 &counterInc)
{
if (m_mode >= CBC && (iv.isEmpty() || iv.size() != m_blocklen))
if (m_mode >= CBC && (iv1.isEmpty() || iv1.size() != m_blocklen))
return QByteArray();

QByteArray expandedKey = expandKey(key);
QByteArray alignedText(rawText);

Expand Down Expand Up @@ -519,8 +535,8 @@ QByteArray QAESEncryption::encode(const QByteArray &rawText, const QByteArray &k
if (m_aesNIAvailable){
quint8 in[alignedText.size()];
memcpy(in, alignedText.constData(), alignedText.size());
quint8 ivec[iv.size()];
memcpy(ivec, iv.data(), iv.size());
quint8 ivec[iv1.size()];
memcpy(ivec, iv1.data(), iv1.size());
char out[alignedText.size()];
memset(out, 0x00, alignedText.size());
char expKey[expandedKey.size()];
Expand All @@ -535,7 +551,7 @@ QByteArray QAESEncryption::encode(const QByteArray &rawText, const QByteArray &k
}
#endif
QByteArray ret;
QByteArray ivTemp(iv);
QByteArray ivTemp(iv1);
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)));
Expand All @@ -544,9 +560,49 @@ QByteArray QAESEncryption::encode(const QByteArray &rawText, const QByteArray &k
return ret;
}
break;
case CCBC: {
QByteArray ret;
QByteArray iv1Temp(iv1);
QByteArray iv2Temp(iv2);
for(int i=0; i < alignedText.size(); i+= m_blocklen) {
iv2Temp = incrBytes(iv2Temp, counterInc);
QByteArray alignedBlock = alignedText.mid(i, m_blocklen);
alignedText.replace(i, m_blocklen, byteXor(alignedBlock,iv1Temp));
ret.append(byteXor(cipher(expandedKey, alignedText.mid(i, m_blocklen)), iv2Temp));
iv1Temp = ret.mid(i, m_blocklen);
}
return ret;
}
break;
case PCBC: {
QByteArray ret; //ENCODE
QByteArray ivTemp(iv1);
for(int i=0; i < alignedText.size(); i+= m_blocklen) {
QByteArray alignedBlock = alignedText.mid(i, m_blocklen);
alignedText.replace(i, m_blocklen, byteXor(alignedBlock,ivTemp));
ret.append(cipher(expandedKey, alignedText.mid(i, m_blocklen)));
ivTemp = byteXor(ret.mid(i, m_blocklen), alignedBlock);
}
return ret;
}
break;
case CPCBC: {
QByteArray ret;
QByteArray iv1Temp(iv1);
QByteArray iv2Temp(iv2);
for(int i=0; i < alignedText.size(); i+= m_blocklen) {
iv2Temp = incrBytes(iv2Temp, counterInc);
QByteArray alignedBlock = alignedText.mid(i, m_blocklen);
alignedText.replace(i, m_blocklen, byteXor(alignedBlock,iv1Temp));
ret.append(byteXor(cipher(expandedKey, alignedText.mid(i, m_blocklen)), iv2Temp));
iv1Temp = byteXor(ret.mid(i, m_blocklen), alignedBlock);
}
return ret;
}
break;
case CFB: {
QByteArray ret;
ret.append(byteXor(alignedText.left(m_blocklen), cipher(expandedKey, iv)));
ret.append(byteXor(alignedText.left(m_blocklen), cipher(expandedKey, iv1)));
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),
Expand All @@ -558,7 +614,7 @@ QByteArray QAESEncryption::encode(const QByteArray &rawText, const QByteArray &k
case OFB: {
QByteArray ret;
QByteArray ofbTemp;
ofbTemp.append(cipher(expandedKey, iv));
ofbTemp.append(cipher(expandedKey, iv1));
for (int i=m_blocklen; i < alignedText.size(); i += m_blocklen){
ofbTemp.append(cipher(expandedKey, ofbTemp.right(m_blocklen)));
}
Expand All @@ -571,9 +627,9 @@ QByteArray QAESEncryption::encode(const QByteArray &rawText, const QByteArray &k
return QByteArray();
}

QByteArray QAESEncryption::decode(const QByteArray &rawText, const QByteArray &key, const QByteArray &iv)
QByteArray QAESEncryption::decode(const QByteArray &rawText, const QByteArray &key, const QByteArray &iv1, const QByteArray &iv2, const quint8 &counterInc)
{
if (m_mode >= CBC && (iv.isEmpty() || iv.size() != m_blocklen))
if (m_mode >= CBC && (iv1.isEmpty() || iv1.size() != m_blocklen))
return QByteArray();

QByteArray ret;
Expand All @@ -586,16 +642,50 @@ QByteArray QAESEncryption::decode(const QByteArray &rawText, const QByteArray &k
ret.append(invCipher(expandedKey, rawText.mid(i, m_blocklen)));
break;
case CBC: {
QByteArray ivTemp(iv);
QByteArray ivTemp(iv1);
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;
case CCBC: {
QByteArray iv1Temp(iv1); //DECODE
QByteArray iv2Temp(iv2);
for(int i=0; i < rawText.size(); i+= m_blocklen){
iv2Temp = incrBytes(iv2Temp, counterInc);
QByteArray rawBlock = rawText.mid(i, m_blocklen);
ret.append(invCipher(expandedKey, byteXor(rawBlock, iv2Temp))); //
ret.replace(i, m_blocklen, byteXor(ret.mid(i, m_blocklen),iv1Temp));
iv1Temp = ret.mid(i, m_blocklen);
}
}
break;
case PCBC: {
QByteArray ivTemp(iv1);
for(int i=0; i < rawText.size(); i+= m_blocklen){
QByteArray rawBlock = rawText.mid(i, m_blocklen);
ret.append(invCipher(expandedKey, rawBlock));
ret.replace(i, m_blocklen, byteXor(ret.mid(i, m_blocklen),ivTemp));
ivTemp = byteXor(ret.mid(i, m_blocklen), rawBlock);
}
}
break;
case CPCBC: {
QByteArray iv1Temp(iv1); //DECODE
QByteArray iv2Temp(iv2);
for(int i=0; i < rawText.size(); i+= m_blocklen){
iv2Temp = incrBytes(iv2Temp, counterInc);
QByteArray rawBlock = rawText.mid(i, m_blocklen);
ret.append(invCipher(expandedKey, byteXor(rawBlock, iv2Temp))); //
ret.replace(i, m_blocklen, byteXor(ret.mid(i, m_blocklen),iv1Temp));
iv1Temp = byteXor(ret.mid(i, m_blocklen), rawBlock);
}
}
break;
case CFB: {
ret.append(byteXor(rawText.mid(0, m_blocklen), cipher(expandedKey, iv)));
ret.append(byteXor(rawText.mid(0, m_blocklen), cipher(expandedKey, iv1)));
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),
Expand All @@ -606,7 +696,7 @@ QByteArray QAESEncryption::decode(const QByteArray &rawText, const QByteArray &k
break;
case OFB: {
QByteArray ofbTemp;
ofbTemp.append(cipher(expandedKey, iv));
ofbTemp.append(cipher(expandedKey, iv1));
for (int i=m_blocklen; i < rawText.size(); i += m_blocklen){
ofbTemp.append(cipher(expandedKey, ofbTemp.right(m_blocklen)));
}
Expand Down
8 changes: 6 additions & 2 deletions qaesencryption.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ class QTAESSHARED_EXPORT QAESEncryption : public QObject
enum Mode {
ECB,
CBC,
CCBC,
PCBC,
CPCBC,
CFB,
OFB
};
Expand All @@ -49,8 +52,8 @@ class QTAESSHARED_EXPORT QAESEncryption : public QObject
QAESEncryption(QAESEncryption::Aes level, QAESEncryption::Mode mode,
QAESEncryption::Padding padding = QAESEncryption::ISO);

QByteArray encode(const QByteArray &rawText, const QByteArray &key, const QByteArray &iv = QByteArray());
QByteArray decode(const QByteArray &rawText, const QByteArray &key, const QByteArray &iv = QByteArray());
QByteArray encode(const QByteArray &rawText, const QByteArray &key, const QByteArray &iv1 = QByteArray(), const QByteArray &iv2 = QByteArray(), const quint8 &counterInc = 64);
QByteArray decode(const QByteArray &rawText, const QByteArray &key, const QByteArray &iv1 = QByteArray(), const QByteArray &iv2 = QByteArray(), const quint8 &counterInc = 64);
QByteArray removePadding(const QByteArray &rawText);
QByteArray expandKey(const QByteArray &key);

Expand Down Expand Up @@ -107,6 +110,7 @@ public Q_SLOTS:
QByteArray cipher(const QByteArray &expKey, const QByteArray &in);
QByteArray invCipher(const QByteArray &expKey, const QByteArray &in);
QByteArray byteXor(const QByteArray &a, const QByteArray &b);
QByteArray incrBytes(const QByteArray &bytes, const quint8 &inc = 8, const quint64 &count = 1);

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