Skip to content

Commit

Permalink
Padding (#57)
Browse files Browse the repository at this point in the history
delete zero padding
  • Loading branch information
SergeyBel authored Feb 4, 2022
1 parent 3eb232f commit b67a817
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 114 deletions.
15 changes: 11 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ C++ AES(Advanced Encryption Standard) implementation

![Build Status](https://github.com/SergeyBel/AES/actions/workflows/aes-ci.yml/badge.svg?branch=master)

# Usage

**This class is very simple to use:**
```c++
Expand Down Expand Up @@ -33,14 +34,20 @@ c = aes.EncryptECB(plain, key);
ECB, CBC, CFB modes are supported.


You can read more about AES here:

https://en.wikipedia.org/wiki/Advanced_Encryption_Standard

http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.197.pdf
# Padding
This library do not provide any padding because padding is not part of AES standard. Plaintext and ciphertext length in bytes must be divisible by 16. If length doesn't satisfy this condition exception will be thrown


**Development:**
# Links


* [Wiki](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard)
* [NIST](https://www.nist.gov/publications/advanced-encryption-standard-aes)

# Development:

1. `git clone https://github.com/SergeyBel/AES.git`
1. `docker-compose build`
1. `docker-compose up -d`
Expand Down
3 changes: 1 addition & 2 deletions speedtest/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ int main()
{
const unsigned int MEGABYTE = 1024 * 1024 * sizeof(unsigned char);

unsigned int len = 0;
unsigned int megabytesCount = 10;
unsigned int plainLength = megabytesCount * MEGABYTE;
unsigned char key[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
Expand All @@ -38,7 +37,7 @@ int main()

AES aes(AESKeyLength::AES_256);
unsigned long start = getMicroseconds();
unsigned char *out = aes.EncryptECB(plain, plainLength, key, len);
unsigned char *out = aes.EncryptECB(plain, plainLength, key);
unsigned long delta = getMicroseconds() - start;

double speed = (double)megabytesCount / delta * MICROSECONDS;
Expand Down
73 changes: 27 additions & 46 deletions src/AES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,25 @@ AES::AES(AESKeyLength keyLength)
}


unsigned char * AES::EncryptECB(unsigned char in[], unsigned int inLen, unsigned char key[], unsigned int &outLen)
unsigned char * AES::EncryptECB(unsigned char in[], unsigned int inLen, unsigned char key[])
{
outLen = GetPaddingLength(inLen);
unsigned char *alignIn = PaddingNulls(in, inLen, outLen);
unsigned char *out = new unsigned char[outLen];
CheckLength(inLen);
unsigned char *out = new unsigned char[inLen];
unsigned char *roundKeys = new unsigned char[4 * Nb * (Nr + 1)];
KeyExpansion(key, roundKeys);
for (unsigned int i = 0; i < outLen; i+= blockBytesLen)
for (unsigned int i = 0; i < inLen; i+= blockBytesLen)
{
EncryptBlock(alignIn + i, out + i, roundKeys);
EncryptBlock(in + i, out + i, roundKeys);
}

delete[] alignIn;
delete[] roundKeys;

return out;
}

unsigned char * AES::DecryptECB(unsigned char in[], unsigned int inLen, unsigned char key[])
{
CheckLength(inLen);
unsigned char *out = new unsigned char[inLen];
unsigned char *roundKeys = new unsigned char[4 * Nb * (Nr + 1)];
KeyExpansion(key, roundKeys);
Expand All @@ -57,31 +56,30 @@ unsigned char * AES::DecryptECB(unsigned char in[], unsigned int inLen, unsigned
}


unsigned char *AES::EncryptCBC(unsigned char in[], unsigned int inLen, unsigned char key[], unsigned char * iv, unsigned int &outLen)
unsigned char *AES::EncryptCBC(unsigned char in[], unsigned int inLen, unsigned char key[], unsigned char * iv)
{
outLen = GetPaddingLength(inLen);
unsigned char *alignIn = PaddingNulls(in, inLen, outLen);
unsigned char *out = new unsigned char[outLen];
CheckLength(inLen);
unsigned char *out = new unsigned char[inLen];
unsigned char *block = new unsigned char[blockBytesLen];
unsigned char *roundKeys = new unsigned char[4 * Nb * (Nr + 1)];
KeyExpansion(key, roundKeys);
memcpy(block, iv, blockBytesLen);
for (unsigned int i = 0; i < outLen; i+= blockBytesLen)
for (unsigned int i = 0; i < inLen; i+= blockBytesLen)
{
XorBlocks(block, alignIn + i, block, blockBytesLen);
XorBlocks(block, in + i, block, blockBytesLen);
EncryptBlock(block, out + i, roundKeys);
memcpy(block, out + i, blockBytesLen);
}

delete[] block;
delete[] alignIn;
delete[] roundKeys;

return out;
}

unsigned char *AES::DecryptCBC(unsigned char in[], unsigned int inLen, unsigned char key[], unsigned char * iv)
{
CheckLength(inLen);
unsigned char *out = new unsigned char[inLen];
unsigned char *block = new unsigned char[blockBytesLen];
unsigned char *roundKeys = new unsigned char[4 * Nb * (Nr + 1)];
Expand All @@ -100,33 +98,32 @@ unsigned char *AES::DecryptCBC(unsigned char in[], unsigned int inLen, unsigned
return out;
}

unsigned char *AES::EncryptCFB(unsigned char in[], unsigned int inLen, unsigned char key[], unsigned char * iv, unsigned int &outLen)
unsigned char *AES::EncryptCFB(unsigned char in[], unsigned int inLen, unsigned char key[], unsigned char * iv)
{
outLen = GetPaddingLength(inLen);
unsigned char *alignIn = PaddingNulls(in, inLen, outLen);
unsigned char *out = new unsigned char[outLen];
CheckLength(inLen);
unsigned char *out = new unsigned char[inLen];
unsigned char *block = new unsigned char[blockBytesLen];
unsigned char *encryptedBlock = new unsigned char[blockBytesLen];
unsigned char *roundKeys = new unsigned char[4 * Nb * (Nr + 1)];
KeyExpansion(key, roundKeys);
memcpy(block, iv, blockBytesLen);
for (unsigned int i = 0; i < outLen; i+= blockBytesLen)
for (unsigned int i = 0; i < inLen; i+= blockBytesLen)
{
EncryptBlock(block, encryptedBlock, roundKeys);
XorBlocks(alignIn + i, encryptedBlock, out + i, blockBytesLen);
XorBlocks(in + i, encryptedBlock, out + i, blockBytesLen);
memcpy(block, out + i, blockBytesLen);
}

delete[] block;
delete[] encryptedBlock;
delete[] alignIn;
delete[] roundKeys;

return out;
}

unsigned char *AES::DecryptCFB(unsigned char in[], unsigned int inLen, unsigned char key[], unsigned char * iv)
{
CheckLength(inLen);
unsigned char *out = new unsigned char[inLen];
unsigned char *block = new unsigned char[blockBytesLen];
unsigned char *encryptedBlock = new unsigned char[blockBytesLen];
Expand All @@ -147,24 +144,11 @@ unsigned char *AES::DecryptCFB(unsigned char in[], unsigned int inLen, unsigned
return out;
}

unsigned char * AES::PaddingNulls(unsigned char in[], unsigned int inLen, unsigned int alignLen)
{
unsigned char *alignIn = new unsigned char[alignLen];
memcpy(alignIn, in, inLen);
memset(alignIn + inLen, 0x00, alignLen - inLen);
return alignIn;
}

unsigned int AES::GetPaddingLength(unsigned int len)
void AES::CheckLength(unsigned int len)
{
unsigned int lengthWithPadding = (len / blockBytesLen);
if (len % blockBytesLen) {
lengthWithPadding++;
if (len % blockBytesLen != 0) {
throw std::length_error("Plaintext length must be divisible by " + blockBytesLen);
}

lengthWithPadding *= blockBytesLen;

return lengthWithPadding;
}

void AES::EncryptBlock(unsigned char in[], unsigned char out[], unsigned char *roundKeys)
Expand Down Expand Up @@ -507,9 +491,8 @@ unsigned char *AES::VectorToArray(std::vector<unsigned char> a)

std::vector<unsigned char> AES::EncryptECB(std::vector<unsigned char> in, std::vector<unsigned char> key)
{
unsigned int outLen = 0;;
unsigned char *out = EncryptECB(VectorToArray(in), (unsigned int)in.size(), VectorToArray(key), outLen);
std::vector<unsigned char> v = ArrayToVector(out, outLen);
unsigned char *out = EncryptECB(VectorToArray(in), (unsigned int)in.size(), VectorToArray(key));
std::vector<unsigned char> v = ArrayToVector(out, in.size());
delete []out;
return v;
}
Expand All @@ -525,9 +508,8 @@ std::vector<unsigned char> AES::DecryptECB(std::vector<unsigned char> in, std::v

std::vector<unsigned char> AES::EncryptCBC(std::vector<unsigned char> in, std::vector<unsigned char> key, std::vector<unsigned char> iv)
{
unsigned int outLen = 0;
unsigned char *out = EncryptCBC(VectorToArray(in), (unsigned int)in.size(), VectorToArray(key), VectorToArray(iv), outLen);
std::vector<unsigned char> v = ArrayToVector(out, outLen);
unsigned char *out = EncryptCBC(VectorToArray(in), (unsigned int)in.size(), VectorToArray(key), VectorToArray(iv));
std::vector<unsigned char> v = ArrayToVector(out, in.size());
delete [] out;
return v;
}
Expand All @@ -542,9 +524,8 @@ std::vector<unsigned char> AES::DecryptCBC(std::vector<unsigned char> in, std::v

std::vector<unsigned char> AES::EncryptCFB(std::vector<unsigned char> in, std::vector<unsigned char> key, std::vector<unsigned char> iv)
{
unsigned int outLen = 0;
unsigned char *out = EncryptCFB(VectorToArray(in), (unsigned int)in.size(), VectorToArray(key), VectorToArray(iv), outLen);
std::vector<unsigned char> v = ArrayToVector(out, outLen);
unsigned char *out = EncryptCFB(VectorToArray(in), (unsigned int)in.size(), VectorToArray(key), VectorToArray(iv));
std::vector<unsigned char> v = ArrayToVector(out, in.size());
delete [] out;
return v;
}
Expand Down
10 changes: 4 additions & 6 deletions src/AES.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,8 @@ class AES
void InvMixColumns(unsigned char **state);

void InvShiftRows(unsigned char **state);

unsigned char* PaddingNulls(unsigned char in[], unsigned int inLen, unsigned int alignLen);

unsigned int GetPaddingLength(unsigned int len);
void CheckLength(unsigned int len);

void KeyExpansion(unsigned char key[], unsigned char w[]);

Expand All @@ -66,15 +64,15 @@ class AES
public:
explicit AES(AESKeyLength keyLength = AESKeyLength::AES_256);

unsigned char *EncryptECB(unsigned char in[], unsigned int inLen, unsigned char key[], unsigned int &outLen);
unsigned char *EncryptECB(unsigned char in[], unsigned int inLen, unsigned char key[]);

unsigned char *DecryptECB(unsigned char in[], unsigned int inLen, unsigned char key[]);

unsigned char *EncryptCBC(unsigned char in[], unsigned int inLen, unsigned char key[], unsigned char *iv, unsigned int &outLen);
unsigned char *EncryptCBC(unsigned char in[], unsigned int inLen, unsigned char key[], unsigned char *iv);

unsigned char *DecryptCBC(unsigned char in[], unsigned int inLen, unsigned char key[], unsigned char *iv);

unsigned char *EncryptCFB(unsigned char in[], unsigned int inLen, unsigned char key[], unsigned char *iv, unsigned int &outLen);
unsigned char *EncryptCFB(unsigned char in[], unsigned int inLen, unsigned char key[], unsigned char *iv);

unsigned char *DecryptCFB(unsigned char in[], unsigned int inLen, unsigned char key[], unsigned char *iv);

Expand Down
Loading

0 comments on commit b67a817

Please sign in to comment.