Openssl encrypt large file - encryption

I'm trying to encrypt a large file using OpenSSL AES_set_encrypt_key & AES_cbc_encrypt functions. I've written a C++ program to encrypt a file using AES_set_encrypt_key & AES_cbc_encrypt. The contents is got from a large file. I'm allocating memory in heap and calling AES_cbc_encrypt. But I observed only 8 bytes are getting encrypted. But when I allocate memory on stack, the function is working properly. Any help is highly appreciated.
unsigned char enc_out[encsize]; //working
unsigned char *enc_out = new unsigned char[encsize];//not working
`
QByteArray WebMessages::encryption(QString e_text) {
QByteArray ba = e_text.toLatin1();
char *encinput = strdup(ba.constData());
const int UserDataSize = strlen(encinput);
unsigned char *test2 = new unsigned char[UserDataSize];
for (int i = 0; i < UserDataSize; i++) {
test2[i] = encinput[i];
// qDebug() << test2[i];
}
int keylength = 128;
unsigned char aes_key[] = "";
unsigned char iv_enc[] = "";
unsigned char iv_dec[] = "";
const int encsize =
((UserDataSize + AES_BLOCK_SIZE) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
qDebug() << "$$$$$$$$$$$" << UserDataSize << AES_BLOCK_SIZE << encsize
<< sizeof(unsigned char *); //1481 16 1488 8
unsigned char enc_out[encsize];
// unsigned char *enc_out = new unsigned char[encsize];
AES_KEY enc_key;
AES_set_encrypt_key(aes_key, keylength, &enc_key);
AES_cbc_encrypt(test2, enc_out, UserDataSize, &enc_key, iv_enc,
AES_ENCRYPT);
qDebug() << "enc_out" << enc_out << sizeof(enc_out);
}
`

Related

QDataStream not initialized while reading buffer from ipc fifo file descriptor

I want to communicate between two application using fifo (ipc), I have created a fifo by "mkfifo MyPipe" command.
first App:
....
....
fd = open("MyPipe", O_NONBLOCK | O_WRONLY);
QByteArray buf;
QDataStream bdwr(&buf,QIODevice::WriteOnly);
bdwr.setVersion(kDSVersion);
myclassObjWr.lname = "AAAAA";
myclassObjWr.fname = "BBBBB";
bdwr << myclassObjWr.lname << myclassObjWr.fname ;
ssize_t written = write(fd,buf.data() , buf.length());
.....
.....
second App:
....
....
fd = open("MyPipe", O_NONBLOCK | O_RDONLY);
ssize_t nread;
QByteArray rxbuf;
static const QDataStream::Version kDSVersion = QDataStream::Qt_5_12;
QDataStream bdrd(&rxbuf, QIODevice::ReadWrite);
bdrd.setVersion(kDSVersion);
nread = read(fd, rxbuf.data(),200);
if ( nread > 0)
{
bdrd.writeRawData(rxbuf.data(),nread);
bdrd >> myclassObjrd.lname >> myclassObjrd.fname;
qDebug() << "lname: " << myclassObjrd.lname;
}
....
....
After reading the ipc fifo the "rxbuf" is initialized completely but "myclassObjrd.lname" and "myclassObjrd.fname" both are empty and do not initialize.
It was solved by using an intermediate unsigned char buffer to initialize QByteArray in the Second App as follows.
# ...
ssize_t nread;
QByteArray buf;
unsigned char* rxbuf;
static const QDataStream::Version kDSVersion = QDataStream::Qt_5_12;
QDataStream bdrd(&buf, QIODevice::ReadOnly);
bdrd.setVersion(kDSVersion);
rxbuf = (unsigned char*)malloc(200);
nread = read(fd, rxbuf,200);
if ( nread > 0)
{
for (int i = 0 ; i < nread; i++) {
buf[i] = rxbuf[i] ; //init QByteArray
}
bdrd >> myclassObjrd.lname >> myclassObjrd.fname;
qDebug() << "lname: " << myclassObjrd.lname;
}
# ...

Update UDP checksum in fragmented packets

I'm building a network appliance. I need to support NAT and IP packet fragmentation. When I change the source or destination address of a UDP packet, I have to correct the UDP checksum (and the IP checksum too, but that's trivial). When the packet is fragmented, I'd have to collect all the fragments to recalculate the checksum. I know the old address and the new address. I'd like to:
Un-negate the checksum
Subtract the old address
Add the new address
Re-reduce the sum and negate
This process doesn't always work. Is there any way to update the checksum versus having to recalculate it from scratch?
I've tried:
long CalcCheckSumAdd(unsigned char *pbHeader, int iSize, long lInitial){
long lSum = lInitial;
while (iSize > 1){
lSum += *((unsigned short*)pbHeader);
pbHeader += 2;
iSize -= 2;
}
if (iSize > 0) lSum += *pbHeader;
return lSum;
}
long CalcCheckSumSubract(unsigned char *pbHeader, int iSize, long lInitial){
long lSum = lInitial;
while (iSize > 1){
lSum -= *((unsigned short*)pbHeader);
pbHeader += 2;
iSize -= 2;
}
if (iSize > 0) lSum -= *pbHeader;
return lSum;
}
unsigned short CalcCheckSumFinish(long lSum){
while (lSum >> 16){
lSum = (lSum & 0xFFFF) + (lSum >> 16);
}
return (unsigned short)(~lSum);
}
long CalcCheckSumUnfinish(unsigned short usSum){
// Can't totally undo lossy finish logic
return ~usSum;
}
unsigned short CalcCheckSumUpdateAddress(unsigned short usOldSum, unsigned long ulOldAddress, unsigned long ulNewAddress){
long lSumFixed = CalcCheckSumUnfinish(usOldSum);
lSumFixed = CalcCheckSumSubract((unsigned char*)&ulOldAddress,sizeof(ulOldAddress),lSumFixed);
lSumFixed = CalcCheckSumAdd((unsigned char*)&ulNewAddress,sizeof(ulNewAddress),lSumFixed);
return CalcCheckSumFinish(lSumFixed);
}
Thanks!
EDIT: Added unit test code below
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
long CalcCheckSumAdd(unsigned char *pbHeader, int iSize, long lInitial){
long lSum = lInitial;
while (iSize > 1){
lSum += *((unsigned short*)pbHeader);
pbHeader += 2;
iSize -= 2;
}
if (iSize > 0) lSum += *pbHeader;
return lSum;
}
unsigned short CalcCheckSumFinish(long lSum){
while (lSum >> 16){
lSum = (lSum & 0xFFFF) + (lSum >> 16);
}
return (unsigned short)(~lSum);
}
void Randomize(unsigned char *pucPacket, unsigned long ulSize){
for (unsigned long ulByte = 0; ulByte < ulSize; ulByte++){
pucPacket[ulByte] = (unsigned char)(255 * rand() / RAND_MAX);
}
}
unsigned short Calc(unsigned char *pucPacket, unsigned long ulSize){
long lSum = CalcCheckSumAdd(pucPacket,ulSize,0);
return CalcCheckSumFinish(lSum);
}
unsigned short Fix(unsigned short usOrig, unsigned int uiOld, unsigned int uiNew){
// TODO: Replace this with something that makes main never fail
usOrig -= uiOld & 0xffff;
usOrig -= uiOld >> 16 & 0xffff;
usOrig += uiNew & 0xffff;
usOrig += uiNew >>16 & 0xffff;
return usOrig;
}
void Break(unsigned char *pucPacket, unsigned int *puiOld, unsigned int *puiNew){
unsigned int *puiChange = (unsigned int*)pucPacket;
*puiOld = *puiChange;
Randomize((unsigned char*)puiNew,sizeof(unsigned int));
*puiChange = *puiNew;
}
void PrintBuffer(const char *szName, unsigned char *pucBuff, unsigned int uiSize){
printf("%s: ",szName);
for (unsigned int uiByte = 0; uiByte < uiSize; uiByte++){
printf("%02X",(unsigned int)pucBuff[uiByte]);
}
printf("\n");
}
void PrintTestCase(unsigned char *pucOrig, unsigned char *pucChanged, unsigned int uiSize, unsigned short usOrig, unsigned short usChanged, unsigned short usFixed){
PrintBuffer("Original Buffer",pucOrig,uiSize);
PrintBuffer("Changed Buffer ",pucChanged,uiSize);
printf("Orig checksum: %04X\n",(unsigned int)usOrig);
printf("Changed checksum: %04X\n",(unsigned int)usChanged);
printf("Fixed checksum: %04X\n",(unsigned int)usFixed);
}
int main(){
srand((unsigned int)time(nullptr));
unsigned char pucDataOrig[100];
unsigned char pucDataChanged[100];
bool bTestFailed = false;
while (!bTestFailed){
Randomize(pucDataOrig,sizeof(pucDataOrig));
memcpy(pucDataChanged,pucDataOrig,sizeof(pucDataOrig));
unsigned short usOrig = Calc(pucDataOrig,sizeof(pucDataOrig));
unsigned int uiOld = 0,
uiNew = 0;
Break(pucDataChanged,&uiOld,&uiNew);
unsigned short usFixed = Fix(usOrig,uiOld,uiNew);
unsigned short usChanged = Calc(pucDataChanged,sizeof(pucDataChanged));
if (usChanged == usFixed){
printf(".");
}else{
printf("\nTest case failed\n");
PrintTestCase(pucDataOrig,pucDataChanged,sizeof(pucDataOrig),usOrig,usChanged,usFixed);
bTestFailed = true;
}
}
return 0;
}
You are right, the solution above works only on some cases, but I have a new implem that works for all kind of packet (fragmented or not, UDP, TCP, IP). Here is the implem:
/* incremental checksum update */
static inline void
cksum_update(uint16_t *csum, uint32_t from, uint32_t to)
{
uint32_t sum, csum_c, from_c, res, res2, ret, ret2;
csum_c = ~((uint32_t)*csum);
from_c = ~from;
res = csum_c + from_c;
ret = res + (res < from_c);
res2 = ret + to;
ret2 = res2 + (res2 < to);
sum = ret2;
sum = (sum & 0xffff) + (sum >> 16);
sum = (sum & 0xffff) + (sum >> 16);
*csum = (uint16_t)~sum;
}
You can now use this function when you translated you packet address and before sending:
/* Update L4 checksums on all packet a part from [2nd, n] fragment */
switch (IS_FRAG(ipv4_hdr) ? 0 : ipv4_hdr->next_proto_id) {
case IPPROTO_TCP:
{
struct tcp_hdr *tcp_hdr = tcp_header(pkt);
/* Compute TCP checksum using incremental update */
cksum_update(&tcp_hdr->cksum, old_ip_addr, *address);
break;
}
case IPPROTO_UDPLITE:
case IPPROTO_UDP:
{
struct udp_hdr *udp_hdr = udp_header(pkt);
/* Compute UDP checksum using incremental update */
cksum_update(&udp_hdr->dgram_cksum, old_ip_addr, *address);
break;
}
default:
break;
}
You have to substract the old ip address and add the new one on the udp checksum, here is the pseudo code:
udp_hdr->dgram_cksum -= old_ipv4_addr & 0xffff;
udp_hdr->dgram_cksum -= old_ipv4_addr >> 16 & 0xffff;
udp_hdr->dgram_cksum += new_ipv4_addr & 0xffff;
udp_hdr->dgram_cksum += new_ipv4_addr >>16 & 0xffff;
That should handle UDP checksum on IP fragments.

Qbytearray byte to int and storing it as string value

I want to convert byte data that stored in QBytearray into string value. that string value am using it for displaying in ui window..
QByteArray array;
array.append( 0x02 );
array.append( 0xC1);
qDebug()<<( uint )array[0]<<" "<<( uint )array[1];
uint i = 0x00000000;
i |= array[1];
qDebug()<<i;
uint j = 0x00000000 | ( array[0] << 8 );
qDebug()<<j;
i |= j;
bool b = false;
QString str = QString::number( i );
qDebug()<<str;
but the str prints "4294967233"...this code works for some of the bytes like 0x1, 0x45 and for some of other..but this code not working perfectly for all bytes of data into string..please help me with this and write code for this and post it here..thanks
All values equal or bigger than 0x80 interprets in your sample as negative values, so it need cast to unsigned type before bitwise operations.
QByteArray array;
array.append( 0x02 );
array.append( 0xC1);
unsigned int value = 0;
for (int i = 0; i < array.size(); i++)
value = (value << 8) | static_cast<unsigned char>(array[i]);
QString str = QString::number(value);
qDebug() << value << str;

String to hex splitting

I am having a QString :
QString str = "1000140035";
I want to extract each byte from above string like this :--
Unsigned char a = 0x10
Unsigned char b = 0x00
Unsigned char c = 0x14
Unsigned char d = 0x00
Unsigned char e = 0x35
Please suggest how to do this ... tried but failed many times.
QByteArray::fromHex + QString::toLatin1()
const QString str = "1000140035";
const QByteArray data = QByteArray::fromHex( str.toLatin1() );
unsigned char a = data[0];
unsigned char b = data[1];
unsigned char c = data[2];
unsigned char d = data[3];
unsigned char e = data[4];
You can use QString::toInt and set the base to 16 to convert a hex-string to int (or QString::toUInt).
QString str = "1000140035";
while(!str.isEmpty())
{
unsigned char byte = str.left(2).toInt(0, 16);
// do something with byte, store it somewhere or whatever...
str.remove(0, 2);
}
Perhaps this is what you're looking for? The code will parse an arbitrary length hexadecimal string and return an array of 2-digit hexadecimal numbers along with their count. It allocates memory for the result, so it is your responsibility to release it afterwards. The number of extracted numbers is returned through the third argument.
#include <QString>
#include <cmath>
unsigned HexToNum(char c)
{
if(c >= '0' && c <= '9')
return c - '0';
if(c >= 'A' && c <= 'F')
return 15 + c - 'A';
if(c >= 'a' && c <= 'f')
return 15 + c - 'a';
//Non hex char passed, return 0
return 0;
}
void ExtractBytes(const QString& hexString, unsigned char*& result, int& resultNumbersCount)
{
resultNumbersCount = static_cast<int>(ceil(hexString.length() / 2));
result = new unsigned char[resultNumbersCount];
int i, j = -1;
for(i = 0; i < resultNumbersCount; ++i)
result[i] = 0;
for(i = 0; i < hexString.length(); ++i)
{
if(i % 2 == 0)
++j;
result[j] = result[j] * 16 + HexToNum(hexString.at(i).toLatin1());
}
}

Implementing Rc4 algorithm

I need to implement a Rc4 algorithm with a seed: 1 2 3 6 and the plain text cryptology. I am following this guideline we were provided in class, but it's not initializing S correctly.
my output is
and needs to be
My code was previously printing negative values , not sure why but I managed to fix that error. Thought everything was good to go but it's not. Sorry for the pictures, I figured it was easier to explain what I was following for my code structure. I am mod 4 the seed since it contains 4 characters, could that possibly be my error?
#include <iostream>
#include <string>
#include <string.h>
using std::endl;
using std::string;
void swap(unsigned int *x, unsigned int *y);
int main()
{
string plaintext = "cryptology";
char cipherText[256] = { ' ' };
unsigned int S[256] = { 0 };
unsigned int t[256] = { 0 };
unsigned int seed[4] = { 1, 2, 3, 6 }; // seed used for test case 1
unsigned int temp = 0;
int runningTotal = 0;
unsigned int key = 0;
// inilializing s and t
for (int i = 0; i < 256; i++)
{
S[i] = i;
t[i] = seed[i % 4];
}
for (int i = 0; i < 256; i++)
{
runningTotal += S[i] + t[i];
runningTotal %= 256;
swap(&S[runningTotal], &S[i]);
std::cout << S[i] <<" ";
}
runningTotal = 0;
for (int i = 0; i < plaintext.size(); i++)
{
runningTotal %= 256;
swap(&S[i], &S[runningTotal]);
temp = (unsigned int)S[i] + (unsigned int)S[runningTotal];
temp %= 256;
key = S[temp];
std::cout << endl;
cipherText[i] = plaintext[i] ^ key;
}
std::cout << " this is cipher text " << endl;
std::cout << cipherText << endl;
system("pause");
return 0;
}
void swap(unsigned int *x, unsigned int *y)
{
unsigned int temp = 0;
temp = *x;
*x = *y;
*y = temp;
}
Actually I think you're generating S[] correctly. I can only assume you're supposed to do something different with the key. (Perhaps's its an ASCII string instead of four byte values? Check your assignment notes.)
There is a problem later on, however. In the stream generation loop, you're supposed to do the increment and swap operations before you fetch a byte from S[].
for (int k = 0; k < plaintext.size(); k++)
{
i = (i+1) % 256; // increment S[] index
runningTotal = (runningTotal + S[i]) % 256; // swap bytes
swap(&S[i], &S[runningTotal]);
temp = (S[i] + S[runningTotal]) % 256; // fetch byte from S and
cipherText[k] = plaintext[k] ^ S[temp]; // XOR with plaintext
}
NOTE: Although unrelated to your question, your code could be made a lot tidier by using unsigned char values instead of ints. That would eliminate the % 256 instructions that are littered all over the place. (But be careful during initialization, because i<256 will always be true if i is an unsigned char.)

Resources