Check sum and serial port communication - c

I am trying to send a message with a check sum from an USB to serial port converter and back again.
But I can't make it work for some reason even tough I have tried for a hole day. I am starting to think that there is something wrong with the hardware but I thought that it would be a good idea to ask you guys before giving up... I am using cygwin for executing and compiling programs on a windows computer.
I would have liked to attach a picture of the terminal when the program is running but you have to have an reputation of >10 which I ain't :(. So I will have to describe it instead.....
I get the following information from the terminal when I try to send 'a'.
Enter a message: a
The checksum for your message to send is: 97
Your message to send is: a
a#
The checksum of the received message is: 97
The message wasn't properly received!
You received the following: a
a#
I receive what I send, but the check sum for 'a' should be 'a' right? So the string that should have been sent is "aa" instead of "a
a#" or am I completely lost here.
I have attached the relevant parts of the code below (printWhite() etc. change the color of the text and nothing more)
void main(){
regularSend();
regularReceive();
}
void regularSend(){
char buff2s[20];
unsigned char calculatedCS;
printf("Enter a message: ");
fgets(buff2s,15,stdin); // string input from keyboard
calculatedCS=checkSum(buff2s,strlen(buff2s));
printf("The checksum for your message to send is: %i\n",calculatedCS);
buff2s[strlen(buff2s)]=calculatedCS; //adds a checksum
buff2s[strlen(buff2s)]='\0'; //adds a new string terminator
printf("Your message to send is: %s\n",buff2s);
bytes_written=write(fd,buff2s,strlen(buff2s));
sleep(1);
}
void regularReceive(){
unsigned char buffR[20];
unsigned char rCS;
bytes_read=read(fd,buffR,sizeof(buffR)-1);
if(strlen(buffR)<1){
printRed();
printf(" No reply from the serial device! \n");
printWhite();
}
else{
rCS=checkSum(buffR,strlen(buffR)-2); //1 byte extra now
printf("The checksum of the received message is: %i\n", rCS);
true_or_false=check_checkSum(buffR,strlen(buffR)-1);
if(true_or_false==1){
buffR[strlen(buffR)-1]='\0'; //removes checksum
printf("Your message was: %s\n",buffR);
}
else{
printRed();
printf("The message wasn't properly received!\n");
printWhite();
printf("You received the following: %s\n\n",buffR);
}
}
}
unsigned char checkSum(char buff[], unsigned char nbrOfBytes){
unsigned char ic;
unsigned int t_cSum=0;
for (ic=0;ic<nbrOfBytes-1;ic++){
t_cSum=t_cSum+buff[ic];
}
return (unsigned char) t_cSum; //returns a 8bit checksum
}
unsigned char check_checkSum(char buffR_t[], unsigned char nbrOfBytes){ //<- check this
unsigned char r_cSum=checkSum(buffR_t,nbrOfBytes-1); //calculates the expected value of the checksum byte
if(r_cSum==(unsigned char)buffR_t[nbrOfBytes-2]){
printGreen();
printf("A message has been received! \n");
printWhite();
return 1;
}
else{
return 0;
}
}
Is someone able to spot my mistakes(I am almost sure that there is at least 2)? I would appreciate any help in this matter!
Best regards Henrik

As #Roddy pointed out, code is bad for it overwrites the string's \0 with the checksum, then tries to find the string length in the next line of a potentially unterminated string!
buff2s[strlen(buff2s)]=calculatedCS; //adds a checksum
buff2s[strlen(buff2s)]='\0'; //adds a new string terminator
Suggest:
size_t len = strlen(buff2s);
calculatedCS = checkSum(buff2s, len);
buff2s[len] = calculatedCS; //adds a checksum
buff2s[++len] = '\0'; //adds a new string terminator
bytes_written=write(fd, buff2s, len + 1);
Since working with strings, change checksum generator and checker to insure it does not create a '\0'.
unsigned char checkSum(char buff[], size_t nbrOfBytes){
size_t ic;
unsigned int t_cSum = 0;
for (ic=0; ic<nbrOfBytes-1; ic++){
t_cSum += buff[ic];
}
return (unsigned char) (t_cSum % 255 + 1);
}
RegularReceive() will not work. Suggest reading via fgetc() until a '\0' occurs. (or timeout or buffer full). In particular the following is dangerous as it is not known that buffR ends with a '\0' and the next function is strlen(buffR).
bytes_read = read(fd, buffR, sizeof(buffR)-1);
if(strlen(buffR)<1){

buff2s[strlen(buff2s)]=calculatedCS; //adds a checksum
buff2s[strlen(buff2s)]='\0'; //adds a new string terminator
Bad :-(
Just because your string has a null terminator doesn't mean it's nulls all the way beyond. Your first 'strlen' tells you where the current end is. You overwrite that with the checksum, but where the 'new terminator' goes could be anywhere. Do this instead.
int len = strlen(buff2s);
buff2s[len]=calculatedCS; //adds a checksum
buff2s[len+1]='\0'; //adds a new string terminator
(ideally, checking for buffer overflow as well...)

Related

XOR Encrypted Message length is showing wrongly in C [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
Im Encrypting the Original Messages using XOR algorithm by following code in C program. And Finally it gives another different value that message has encrypted. It should return same length even after the message has encrypted.
But, Using strlen(encrypted) it gives less value than original message length. I couldn't recognize why the length of XOR encrypted message is showing less than the original message length. Please find the following the code to solve my problem.
Thanks in Advance!
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char* XORCipher(char* data, char* key, int dataLen, int keyLen) {
char* output = (char*)malloc(sizeof(char)*dataLen);
for(int i = 0; i < dataLen; ++i) {
output[i] = data[i] ^ key[i % keyLen];
}
return output;
}
int main(){
char *msg = "This is a Message from Boss";
char *key = "nandha";
int dataLen = strlen(msg);
int keyLen = strlen(key);
char *encrypt = XORCipher(msg,key,dataLen,keyLen);
printf("\nEncrypted msg is :\n %s",(char*)encrypt);
//The Length of encrypted char size is showing wrongly.
printf("size of Encrypted msg is: %d\n",strlen(encrypt));
encrypt = XORCipher(encrypt,key,strlen(encrypt),keyLen);
printf("\nOriginal msg converted is : %s\n",encrypt);
return 0;
}
When you perform these XOR operations on your string, the resulting values could fall outside the range of printable characters. In particular, if a plaintext character happens to match the key character used to encode it the result will be 0.
In C, a string is actually a sequence of characters terminated by a null byte, i.e. a byte with value 0. Any function that operates on strings looks for this byte to denote the end of the string.
Because your encoding can generate null bytes, your encrypted message is not a string but an array of bytes. Attempting to use a string function on the encrypted message can cause it to stop processing in the middle of the message if it contains a null byte. If the message does not contain a null byte, these string functions will continue to read past the end of the character array until it finds one. Reading past the end of an array or dynamically allocated block of memory invoked undefined behavior.
You need some other way to know how long the encrypted message is. In the case of the XOR encoding you're doing this is easy: the length of the ciphertext is the same as the length of the plaintext. So when decoding, pass in dataLen for the ciphertext length. To print the ciphertext, you need to loop through the bytes and print each one individually rather that trying to print it as a string (which it is not).
Also, after you've decoded, you still don't have a string because there was no null terminating byte added to the end of the decrypted message. You can do this manually after calling decrypting:
// pass in plaintext length as ciphertext length since they are the same
encrypt = XORCipher(encrypt,key,dataLen,keyLen);
// null terminate decrypted string
encrypt[dataLen] = '\0';
The buffer allocated inside of XORCipher doesn't currently allocate enough space for the null terminator, so you need to increase this by 1 to allow for this:
// no need to cast the return value of malloc
// sizeof(char) is guaranteed to be 1, so no need to multiply by it
char* output = malloc(dataLen + 1);
C strings are character arrays that are null terminated. When you allocate your encrypted array with the length of the string, you don't leave room for null termination, so strlen is unable to tell when the string ends, thinking the string ends outside of the actual memory that you allocated. This modification to your xor function will make it work.
char* XORCipher(char* data, char* key, int dataLen, int keyLen) {
char* output = (char*)malloc(sizeof(char)*dataLen+1);
output[dateLen] = 0;
for(int i = 0; i < dataLen; ++i) {
output[i] = data[i] ^ key[i % keyLen];
}
return output;
}
Additionally, if you're xor function gives 0 as an output, strlen will see that as the end of the string, which would give you a string length shorter than the expected output.
Update: I have tested the code and it works.
char* XORCipher(char* data, char* key, unsigned long dataLen, unsigned long keyLen) {
char* output = (char*)malloc(sizeof(char)*dataLen+1);
output[dataLen] = 0;
for(int i = 0; i < dataLen; ++i) {
output[i] = data[i] ^ key[i % keyLen];
}
return output;
}
void printLn(char* toPrint, unsigned long len){
for (unsigned long i = 0; i < len; i++) {
printf("%c", toPrint[i]);
}
printf("\n");
}
int main(){
char *msg = "This is a Message from Boss";
char *key = "nandha";
unsigned long dataLen = strlen(msg);
unsigned long keyLen = strlen(key);
printLn(msg, dataLen);
char* xorMessage = XORCipher(msg, key, dataLen, keyLen);
printLn(xorMessage, dataLen);
xorMessage = XORCipher(xorMessage, key, dataLen, keyLen);
printLn(xorMessage, dataLen);
return 0;
}
Be reminded that xoring can result in null characters in the array that you've allocated, resulting in a terminating character which you might have not intended. To compensate for this, I have added a function to print out based on length since you know this information based on your msg. After xoring twice you should have your original string back, which I my code verified.

Reading Data in C From Socket Until End Character

EDIT: It has been proven in the comments that defining the length instead should produce the same results and would not use any significant extra data. If you are looking for a way to send data between machines running your program(s), sending the length is better than reading until a terminating character. BonzaiThePenguin has some very good points you should look at.
But for educational purposes: I never found good example code that does this for standard C sockets that handles situations where the data is not all received in one packet, or multiple separate messages are contained within one packet. Simply calling recv repeatedly will not work in all cases.
This is one of those questions where I've answered it myself below, but I'm not 100% confident in my response.
It isn't 'dangerous to allow the client to specify the size of the message it is sending'. Most of the protocols in the word do that, including HTTP and SSL. It's only dangerous when implementations don't bounds-check messages properly.
The fatal flaw with your suggestion is that it doesn't work for binary data: you have to introduce an escape character so that the terminating character can appear within a message, and then of course you also need to escape the escape. All this adds processing and data copying at both ends.
Here is what I came up with. I cannot guarantee that this is perfect because I am not a professional, so if there are any mistakes, I (and anyone else looking for help) would greatly appreciate it if someone would point them out.
Context: socket is the socket, buffer is the array that stores all network input, line is the array that stores just one message extracted from buffer (which is what the rest of your program uses), length is the length of both inputted arrays, and recvLength is a pointer to an integer stored outside of the function that is meant to be 0 initially and should not be freed or modified by anything else. That is, it should persist across multiple calls to this function on the same socket. This function returns the length of the data outputted in the line array.
size_t recv_line(int socket, char* buffer, char* line, size_t length, size_t* recvLength){ //receives until '\4' (EOT character) or '\0' (null character)
size_t readHead = 0;
size_t lineIndex = 0;
char currentChar = 0;
while (1){
for (; readHead < *recvLength; readHead = readHead + 1){
currentChar = buffer[readHead];
if (currentChar=='\4' || currentChar=='\0'){ //replace with the end character(s) of your choice
if (DEBUG) printf("Received message===\n%s\n===of length %ld\n", line, lineIndex+1);
memcpy(buffer, buffer + readHead + 1, length-(readHead)); //shift the buffer down
*recvLength -= (readHead + 1); //without the +1, I had an "off by 1" error before!
return lineIndex+1; //success
}
if (readHead >= length){
if (DEBUG) printf("Client tried to overflow the input buffer. Disconnecting client.\n");
*recvLength = 0;
return 0;
}
line[lineIndex] = currentChar;
lineIndex++;
}
*recvLength = recv(socket, buffer + readHead, length, 0);
}
printf("Unknown error in recv_line!\n");
return 0;
}
Simple example usage:
int function_listening_to_network_input(int socket){
char netBuffer[2048];
char lineBuffer[2048];
size_t recvLength = 0;
while (1==1){
size_t length = recv_line(socket, netBuffer, lineBuffer, 2048, &recvLength);
// handle it…
}
return 0;
}
Note that this does not always leave line as a null-terminated string. If you want it to, it's easy to modify.

Make a long string of encrypted substrings in c

I'm trying to create a long string that is produced out of encrypted substrings. For the encryption I'm using AES128 and libmcrypt. The code is working, but I get a shorter output then I should and a beeping sound. I guess it's because I'm using strlen, but I have no idea, how I can avoid that. I will be very grateful for some suggestions. Here is my code:
char *Encrypt( char *key, char *message){
static char *Res;
MCRYPT mfd;
char *IV;
int i, blocks, key_size = 16, block_size = 16;
blocks = (int) (strlen(message) / block_size) + 1;
Res = calloc(1, (blocks * block_size));
mfd = mcrypt_module_open(MCRYPT_RIJNDAEL_128, NULL, "ecb", NULL);
mcrypt_generic_init(mfd, key, key_size, IV);
strncpy(Res, message, strlen(message));
mcrypt_generic(mfd, Res, block_size);
//printf("the encrypted %s\n", Res);
mcrypt_generic_deinit(mfd);
mcrypt_module_close(mfd);
return (Res);
}
char *mkline ( int cols) {
int j;
char seed[] = "thesecretmessage", key1[]="dontusethisinput", key2[]="abadinputforthis";
char *encrypted, *encrypted2, *in = malloc(cols * 16);
encrypted = Encrypt(key1, seed);
sprintf(in, "%s", encrypted);
encrypted2= Encrypt(key2, encrypted);
printf("encrypted2 before for-loop %s\n", encrypted2);
printf("encrypted2 before for loop len %d\n", strlen(encrypted2));
for (j=1; j<cols; j++) {
strcat(in, encrypted2);
memmove(encrypted2, Encrypt(key2, encrypted2),strlen(seed));
printf("encrypted2 %s on position %d\n" , encrypted2,j);
printf("encrypted2 len %d\n", strlen(encrypted2));
}
free(encrypted);
free(encrypted2);
return in;
}
int main(int argc, char *argv[]) {
char *line = mkline(15);
printf("line %s\n", line);
printf("line lenght %d\n", strlen(line));
return 0;
}
You get the beep sound because you are printing control character.
Also strlen return the size until the first '\0' character (because strings are zero terminated). That's why you get length less than you expect since the encrypted message may contain zeroes.
You can do something like this to return the result length:
char *Encrypt(const char *key, const char *message, int *result_len)
{
*result_len = blocks * block_size;
}
Also
memmove(encrypted2, Encrypt(key2, encrypted2),strlen(seed));
This line should produce a memory leak since every time you call Encrypt you call calloc (allocate new memory) which you need to free after you are done.
You probably should use memcpy, memmove is primarly used if there is a chance destination and source may overlap.
The encrypted string you are trying to print contains a stream of bytes where the value of the individual byte ranges from 0 to 255. Because you are using a cryptographically secure algorithm, the distribution of values is very close to even.
Since you are trying to print the encrypted string through a console, the console interprets some of the bytes as control characters (see Bell character) that are unprintable but have other effects instead, such as playing beeps.
Furthermore, strlen isn't doing what you think it should be doing because the encrypted string is not null-terminated, but instead contains zeroes amongst other bytes and they have no special meaning unlike in NULL terminated strings. You need to store the length of the string elsewhere.
Simple, you are treating binary output (any byte value) directly as printable text. Any character wit a code point below 32 (hex 20) isn't. E.g. the ASCII value for BELL (look it up) could be meaningful to you. Print the resulting bytes in hexadecimals and you should be ok.
I should like to add that in general it is good practice to clear any memory that held the plaintext/unencrypted message after you encrypt it if you can. This is not good coding practice, but good cryptology practice.
This can be done by:
memset(buffer, 0, length_of_buffer);
Don't worry, that won't be optimized out by your compiler. It's actually not smart enough to tell if you'll be using that area again or not.

How to send and receive data socket TCP (C/C++) [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the correct way of reading from a TCP socket in C/C++?
I'm trying to develop a TCP client/server. My problem is, when I try to send the data from cliente I do it in one sent.
But my problem appears when I try to receive the data with a specific structure, I mean, the first 8 bytes set a date, the next 10 a name, and undefined number of bytes set a text (this text ends with /r/n/r/n)
The client sends as follows:
char date[8];
char name[10];
char msg[4096];
strcpy(msg,"12/10/12"); //8 bytes
strcat(msg,"Kevin Fire"); //10 bytes
strcat(msg,"abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde\r\n\r\n");
nbytes_sent = send(sock,(char *)msg,sizeof(msg),0);
printf("Bytes_sent: %s -> %i\n",msg,nbytes_sent);
And the server try to parse the data from socket as follows:
char date[8];
char name[10];
char * text;
char buf[1024];
int i=0;
for(i=0; i < 8; i++)
date[i] = '\0';
for(i=0; i < 10; i++)
name[i] = '\0';
nbytes_read=recv(sclient,(char *)date,sizeof(date),0);
if(nbytes_read > 0){
printf("Date: %s (%i)\n",date,nbytes_read);
//cout.flush();
nbytes_read=recv(sclient,(char *)name,sizeof(name),0);
if(nbytes_read > 0){
printf("Name: %s (%i)\n",name,nbytes_read);
//cout.flush();
nbytes_read=recv(sclient,(char *)buf,sizeof(buf),0);
strcpy(text,buf);
while(nbytes_read > 0){
nbytes_read=recv(sclient(char*)buf,sizeof(buf),0);
strcat(text,buf);
}
}
}
printf("Date: %s. Name: %s. Text: %s\n",date,name,text);
Here's a simple "receive all" function:
int recv_all(int sockfd, void *buf, size_t len, int flags)
{
size_t toread = len;
char *bufptr = (char*) buf;
while (toread > 0)
{
ssize_t rsz = recv(sockfd, bufptr, toread, flags);
if (rsz <= 0)
return rsz; /* Error or other end closed cnnection */
toread -= rsz; /* Read less next time */
bufptr += rsz; /* Next buffer position to read into */
}
return len;
}
One (repeated) mistake is:
nbytes_read=recv(sclient,(char *)date,sizeof(date),0);
recv() does not null terminate. This means date will not have a null terminator if sizeof(date) bytes is read. This is a problem when a non-null terminated string is passed as an argument to printf() with "%s" format specifier. If the string is non-null terminated you may see garbage characters appearing after the actual string data. You need to read one less than the target buffer and null terminate or use the format specifier "%*.s" that does not require null termination:
printf("%.*s", n, s); /* Prints first 'n' bytes from 's'. */
Note you can initialise a char[] to all nulls instead of using a for:
char date[8] = "";
or you can use memset().
Adding to #hmjd's find:
declared at the var decls is your text pointer...
char * text;
then later...
strcpy(text,buf);
while(nbytes_read > 0){
nbytes_read=recv(sclient(char*)buf,sizeof(buf),0);
strcat(text,buf);
}
Maybe try setting that 'text' pointer to something beside a random stack value will help as well.
Continuing the barrage, though the following will not necessarily blow up, your date variable as:
char date[8];
on both client and server side The client variable isn't used at all. The server variable, however is:
nbytes_read=recv(sclient,(char *)date,sizeof(date),0);
if(nbytes_read > 0){
Problem is, the date you sent is, in fact, 8 chars wide already: "12/10/12". Therefore, even if you firm-up a null terminator on the end of your string, which you should always do regardless (good practice):
date[ sizeof(date)/sizeof(date[0])-1 ] = 0;
you'll be truncating off the last char of your date.
There are other things wrong with this; we've only pointed out a few. Think about sending length-prefixes with each of these data values in the array, with checks or range to ensure you get what you expected.
Finally, spending some time on the business-end of a debugger would probably do you very well, especially on the server side.

Adaptation problem with the Blowfish Encryption in C

I'm writing a program that implements the Boneh-Franklin Identity Based Encryption. For the actual encryption methods, I use Blowfish which I got from (https://voltar.org/). I'm trying to adapt the blowfish encryption/decryption code to my program. The difference in my program is that I read the message from the standard input, encrypt it and print the encryption, then decrypt it and print the decryption (which should be the original message). Currently, I read the input message up to a "?" character and then try to follow the code from the site. However, the decryption is printed as unreadable characters. I tried to solve this problem but I got stuck. Can you please help me?
//initializations
BF_KEY s_key; //shared key of the blowfish encryption
char plain[1000000]; //the plaintext of the message
char cipher[1000000]; //the ciphertext of the message
char byte; //to hold the byte of the msg
char *token; //points to tokens of the msg
char IV[8]="MY*IV000"; //the initialization vector
int offset = 0; //the offset of encryption
int b_count = 0; //number of bytes in d_buf
char block[8]; //blocks of encryption
char msg[1000000]; //the input msg from the user
int j; //used to read input in a loop with getchar
int i; //for-loop value
int len; //used to calculate lengths different variables
int f; //flag for the setup stage
int q; //used to read input in a loop with getchar
q=0; //reset the index reader
char in; //to read characters
printf("Please enter the message you wish to send:\n");
************ This is my code to read the input message: ***************
//this loop reads the input from the user since C does not
//provide a safe function to read strings with white spaces
while (in != '?'){
in=getchar();
if(in != '?') //dont include the delim character in the string
msg[q++]=in;
}
msg[q]='\0'; //truncate the string by the null character
************ Then I used the code (cited and referenced) for encryption ***************
Of course I modified it as message read from stdin not program args
for(i=0; i<strlen(msg); i++) //copy the input message to plain
plain[i] = msg[i];
//set up the shared key of the BF encryption
BF_set_key(&s_key, strlen(ekey_buf), ekey_buf);
while(1){
for(i=0; i<8; i++) //reinitiate the block of 8 characters each time
block[i] = 0;
strncpy(block, plain+offset, 8);
BF_cbc_encrypt(plain+offset, cipher, 8, &s_key, IV, BF_ENCRYPT);
for(i=0; i<strlen(cipher); i++){
printf("%02x", (unsigned char) cipher[i]);
}
if( strlen(plain+offset)>8 ){ //if there is still more characters
offset += 8; //process the next block of 8 characters
} else
break;
}
//the cipher is correctly printed
************ Then I used the code (cited and referenced) for decryption ***************
Here, I excluded the part where it tokenized the cipher and created the plain char array for decryption, I simply passed the cipher array to be decrypted (as it is output from the encryption function), and stored in the plain char array with length = strlen(cipher)
//set up the shared key of the BF encryption
BF_set_key(&s_key, strlen(dkey_buf), dkey_buf);
BF_cbc_encrypt(cipher, plain, strlen(cipher), &s_key, IV, BF_DECRYPT);
printf("plain after decryption: %s\n", plain);
//HERE IS THE PROBLEM: I get unreadable characters as output of this line
Any help is appreciated. Sorry for the inconvenience and many thanks in advance.
I have a hunch it's a dirty IV, but it's just a guess.
for(i=0; i<8; i++) ivec[i] = 'i';
BF_cbc_encrypt(inputz, outputz, strlen(inputz), &key, ivec, BF_ENCRYPT);
// won't decrypt right:
BF_cbc_encrypt(inputz, outputz, strlen(inputz), &key, ivec, BF_DECRYPT);
// without resetting the ivec to all 'i's, the decryption will fail.
// This would work though:
for(i=0; i<8; i++) ivec[i] = 'i';
BF_cbc_encrypt(inputz, outputz, strlen(inputz), &key, ivec, BF_ENCRYPT);
for(i=0; i<8; i++) ivec[i] = 'i';
BF_cbc_encrypt(inputz, outputz, strlen(inputz), &key, ivec, BF_DECRYPT);
My guess is only correct if every block after the first decrypts correctly though.
Another big problem with strlen(inputz) is that if the strlen() doesn't fall exactly on an 8byte boundary, your decrypt will ultimately fail. I have addressed the problem rather completely as a gist on github.
Check your encoding.
You need to null terminate plain i.e. something like plain[ strlen(dkey_buf) ] = 0 is needed.
Aren't there patent restrictions on using/distributing programs that leverage the IBE algorithm?

Resources