random number problem

Started by
3 comments, last by streamer 16 years, 3 months ago
Hi all. I'm working on protocol for a credit cards. The code looks like:

BYTE buff[256];
...
//writeData
int tvalue = 1, tvalue = 2;
*((int*)&(buff[0]))= tvalue;
buff[5] = rand()%251+1;
buff[6] = rand()%252+1;
*((int*)&(buff[8]))= tvalue2;
//etc...
buff[255] = Callculate_CRC(buff,255);
//then 
EncodeBuffer(&buff);

and store it on credit card. The problem is in buff[5] and buff[6], where I store two random numbers. The point of two random number is to in every call make different array of numbers making it difficult to crack. But there is a problem with these two numbers. After few calls CRC checking fails, and I can't get numbers I've stored, because they have some random values. For example if I store integer in buff[0] (4 byte) of value 100, then after CRC fails I have number on that location like -1218418425 or something similar. But if two rnd numbers are both zero, then nothing happens, everything is ok. CRC checks are ok, decoding is ok. Only if those two bytes are random, every 5th or 6th call fails. What can be the problem? I don't have a clue. Thanks in advance
Advertisement
It sounds like you may have some memory stomping going on. If a specific location in memory is getting corrupted, you might be able be able to use a watch point to trap when it happens.

If you are concerned the storage/restoration may be causing issues, fill in a buffer and copy it. Encode it, decode it and verify the results are the same doing a byte comparision. As you are leaving 2 bytes filled with garbage data in your current stucture, you will pick up some garbage values. You might want to either manually set these to some value or just memset your whole buffer at the start to a known value to get rid of randomness.

I would also suggest either converting to streams unions for writing your data. In my experience, either of these approaches is much less error prone than dealing with the offsets directly.

For example, you could do something like:

struct Entry
{
int nStorage;
int nRandomNumber;
};

union EntryBuffer
{
Entry EntryList[31]; // leave the last 8 bytes for the CRC
BYTE buffer[256];
};

EntryBuffer buff;
buff.EntryList.nStorage = 1;
buff.EntryList.nRandomNumber = rand() % n;
...
buff.buffer[255] = Callculate_CRC(buff,255);
EncodeBuffer(&buff.buffer);

...or something along those lines. Using a binary stream writing class is another option. These are actually pretty simple to put together.
Yes I was thought about memory corruption, but on some logic basis, if memory corruption occurs it is not important if there is a random number or 0 on specific location. Memory will be corrupted anyway.
I'm trying to avoid unions. Some times ago I had problem when I didn't get same values after read/write with messages I used in my network manager. I used unions an I had union like:
struct msg{BYTE msg_type;union big_one{union msg_data{int value;BYTE  data[10];}; // end union msgunion msg2_data{int value1;int value2;BYTE data[8];}; // end union msg2}; // end union big one}; // end struct

The problem was in integers specially on value2, if memory allocation of first byte of integer didn't fall on memory that is dividable by 4 (sizeof(int) = 4) value got some strange value same as in my problem now.
I suspect that this is the problem with linker, but I'm not sure.
Just because of this problem in past I'm using array of bytes, and just cast memory location to int to get value of some variable.

The cast you're using will probably generate the exact same assembly code as using a union would. You moved away from using unions without ever knowing what the real problem was.
Your problems certainly sounds like memory corruption, but you're not showing anywhere near enough code to diagnose it.

However, considering what this is supposed to be for I'm not sure how you're even allowed to post any of the code for it on here. In fact, I'm not sure how you're able to get away with such a poor method of data hiding either. Why does the 'salt' not include all possible values from 0-255?
I work in the security industry myself and also know plenty about magstripe cards. I presume you're planning on writing this to track 3, since I know for certain that tracks 1 and 2 are too small for 256 bytes.

btw you spelt 'calculate' wrong.
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms
Quote:Original post by iMalc
The cast you're using will probably generate the exact same assembly code as using a union would. You moved away from using unions without ever knowing what the real problem was.
Your problems certainly sounds like memory corruption, but you're not showing anywhere near enough code to diagnose it.

However, considering what this is supposed to be for I'm not sure how you're even allowed to post any of the code for it on here. In fact, I'm not sure how you're able to get away with such a poor method of data hiding either. Why does the 'salt' not include all possible values from 0-255?
I work in the security industry myself and also know plenty about magstripe cards. I presume you're planning on writing this to track 3, since I know for certain that tracks 1 and 2 are too small for 256 bytes.

btw you spelt 'calculate' wrong.


Interesting. Yes I'm writing on track 3, but also on track 1 and 2 too. Off course I didn't wrote down, crc calculations, and encryption type, but I think encryption with 512 bit key and 16 byte pincode is strong enough to stand against hacking attempts. Anyway those cards are not developed for banks, it is for one company's 'inner' use.
In first cycle I used all values from 0-255 but I thought that there is some buffer overrun caused by random generation.
Anyway I'm curious what is poor in my method of hiding data?
You can PM me.

This topic is closed to new replies.

Advertisement