简体   繁体   中英

C Program don't have the same result when compiled on linux and windows

When I compile my program with mingw on windows and gcc on linux, the executable file doesn't give me the same result.

This code is supposed to take a file and encrypt it.

But when I need to add some bytes if the last block is not full or if the file is less than 32 bytes, Linux adds the value "0" like I want but on Windows, it doesn't work.

By the way, the hexdump of each isn't similar.

to execute it : ./encrypt [FileIn] [FileOut] 1 [yourKey] [yourIV]

Put anything you want for Key and IV, they are written inside the code for the test(I just put "1" and "1" to don't get an error)

argv[3] needs to be a "1" to encrypt

I'm testing it using a file with "toto" written inside (put anything you want, but be under 32 char because it's what i'm testing for now).

Key and IV are same inside the code to debug, it's not a mistake.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*FUNCTIONS*/
int encrypt(char* in, char* out, char* key, char* primalIv);
int decrypt(char* in, char* out);
void myprint(char* content, int size);
char* xor(char* data, char* key, int size);
void bitStuffing(char* in, int rem);

/*GLOBAL VARIABLES*/
int errorLevel;
int blockSize = 32; /*Tailles de blocs en octet*/

/*CALL : ./main inFile outFile methode key iv*/
/*FILE STRUC : [datas] [stuffing] [stuffingValue] [iv]*/
int main(int argc, char** argv)
{
    /*Support de l'aide à l'utilisateur*/
    if(argc == 2 && !strcmp(argv[1],"help"))
    {
        printf("\nUsage : ./cied [inFile] [outFile] [methode] [key] [iv]\n\n");
        printf("[inFile]  : Input file to use\n");
        printf("[outFile] : Ouput file to use\n");
        printf("[methode] : Encrypt (1) or decrypt (0)\n");
        printf("[key]     : The key to use\n");
        printf("[iv]      : The initialisation vector.\n");
        printf("            (none for decrypt !)\n");
        return 0;       /*Fermeture gratieuse du programme*/
    }

    /*Support des erreurs d'arguments*/
    if(argc != 5 && argc != 6)
    {
        printf("[ERR] Args error!\n");
        printf("[INF] Enter 'help' to display help\n");
        return 1;
    }
    else if(atoi(argv[3]) == 1 && argc != 6)        /*Nombre d'arguments pour chiffrement*/
    {
        printf("[ERR] Args error : given %d when waiting 5!\n",(argc-1));
        printf("[INF] Enter 'help' to display help\n");
        return 1;
    }
    else if(atoi(argv[3]) == 0 && argc != 5)/*Nombre d'arguments pour dechiffrement*/
    {
        printf("[ERR] Args error : given %d when waiting 4!\n",(argc-1));
        printf("[INF] Enter 'help' to display help\n");
        return 1;
    }


    /***Chiffrement et dechiffremet***/
    if(atoi(argv[3]) == 1)
    {
        errorLevel = encrypt(argv[1], argv[2],"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");/*Chiffrement*/
        if(!errorLevel)
        {   
            printf("[INF] finished\n");
        }
        else
        {
            printf("[ERR] An error as occured.\n");
        }
    }
    else if(atoi(argv[3]) == 0)
    {
        errorLevel = decrypt(argv[1], argv[2]);     /*Dechiffrement*/
        if(!errorLevel)
        {   
            printf("[INF] finished\n");
        }
        else
        {
            printf("[ERR] An error as occured.\n");
        }
    }
    else
    {
        printf("[ERR] Wrong method given!");
        printf("[INF] Enter 'help' to display help\n");
        return 1;
    }
    return 0;
}


/*FONCTIONS CORE*/
int encrypt(char* in, char* out, char* key, char* primalIv)
{
    /*Variables*/
    char* block = NULL;
    char* xored = NULL;
    char* iv = NULL;
    int readed;
    int inFileSize;
    int numOfBlock;
    int rem = 0;
    int i;
    FILE *inFile;
    FILE *outFile;

    iv = primalIv;

    /*Ouverture des fichiers*/
    inFile = fopen(in,"rb");
    outFile = fopen(out,"w");

    /*Gestion des erreurs de fichier*/
    if(inFile == NULL)
    {
        printf("[ERR] Problem reading input file. Please check path and permissions.\n");
    }
    else if(outFile == NULL)
    {
        printf("[ERR] Problem reading output file. Please check path and permissions.\n");
    }

    block = malloc(blockSize);

    /*Récupération de la longueur du fichier*/
    fseek(inFile, 0, SEEK_END);
    inFileSize = ftell(inFile);
    rewind(inFile);

    /*Calcul du nombre de bloc et du reste*/
    numOfBlock = inFileSize / blockSize;
    rem = inFileSize % blockSize;
    printf("[INF] File will be split in %d block(s). %d will remain.\n",numOfBlock,rem);
    if(inFileSize < blockSize)
    {
        readed = fread(block,1,blockSize,inFile);
        printf("[INF] readed %d bytes \n",readed);
        /*Bourrage*/
        bitStuffing(block,(blockSize-readed));
        /*Xor avec l'IV*/
        xored = xor(block,iv,blockSize);
        /*Xor avec la clé*/
        xored = xor(xored,key,blockSize);
        /*Sauvegarde du block pour réutilisation en tant qu'IV*/
        iv = xored;
        /*Ecriture dans le fichier*/
        fwrite(xored,1,blockSize,outFile);
    }
    else
    {
        for(i=0;i<numOfBlock;i++)
        {
            printf("qzekonfk le\n");
            readed = fread(block,1,blockSize,inFile); 
            printf("[INF] readed %d bytes \n",readed);
            if(readed != blockSize)
            {
                printf("[WRN] The readed block siez is different than usual !(%d != %d)\n",blockSize,readed);
            }
            /*Xor avec l'IV*/
            printf("IV :\n");
            xored = xor(block,iv,readed);
            /*Xor avec la clé*/
            printf("KEY :\n");
            xored = xor(xored,key,readed);
            /*Sauvegarde du block pour réutilisation en tant qu'IV*/
            iv = xored;
            /*Ecriture dans le fichier*/
            fwrite(xored,1,readed,outFile);
        }
        /*Bourrage*/
        if(rem)
        {
            readed = fread(block,1,blockSize,inFile);
            printf("[INF] readed %d bytes \n",readed);
            /*Bourrage*/
            bitStuffing(block,(blockSize-readed));
            /*Xor avec l'IV*/
            xored = xor(block,iv,readed);
            /*Xor avec la clé*/
            xored = xor(xored,key,readed);
            /*Sauvegarde du block pour réutilisation en tant qu'IV*/
            iv = xored;
            /*Ecriture dans le fichier*/
            fwrite(xored,1,readed,outFile);
        }
    }

    /*Inscription de rem dans le fichier pour préparer le déchiffrement*/
    fprintf(outFile, "%c",rem);

    /*Inscription de l'IV*/
    printf("IV (again):\n");
    fwrite(xor(primalIv,key,blockSize),1,blockSize,outFile);

    /*Free des malloc*/
    free(block);
    free(xored);

    return 0;
}

int decrypt(char* in, char* out)
{

    return 0;
}

/*FONCTIONS UTILITAIRES*/
char* xor(char* data, char* key, int size)
{
    int i;
    char* result = malloc(size);
    for(i=0; i<size; i++)
    {
        result[i] = data[i] ^ key[i];
        printf("  %x ^ %x = %x\n",data[i],key[i],result[i]);
    }
    return result;
}

void myprint(char* content, int size)
{
    int i;
    printf("  ");
    for(i=0;i<=blockSize;i++)
    {
        printf(" %x",content[i]);
    }
    printf("\n");
}

void bitStuffing(char* in, int rem) {
    int i;
    printf("\nBEGIN STUFFING");
    for(i=rem; i<sizeBlock; i++) {
        in[i] = 0;
        /*printf("%x", in[i]);*/
    }
    printf("\nEND STUFFING\n");
}

@alk You're true, i found it just before reading your post. My friend give a wrong value to the bitStuffing() function. He don't need to give the number of empty bytes, but the byte where the loop have to begin. Then it will be

bitStuffing(block, readed);

and not

bitStuffing(block, (blockSize-readed));

For everyone who want a little less code, i create this to have essentially the stuffing :

#include <stdio.h>
#include <stdlib.h>

void bitStuffing(char* in, int rem);
void myprint(char* content, int size);
int blockSize = 32;

int main()
{
    char* block;
    int inFileSize = 4; /*In my example, the file used is a text file containing "toto"*/
    int readed;
    FILE *outFile;
    readed = inFileSize % blockSize; /*Getting the number of bits to stuff*/
    block  = malloc(blockSize);
    block[0] = "t";
    block[1] = "o";
    block[2] = "t";
    block[3] = "o";
    bitStuffing(block, readed);
    outFile  = fopen("C:/Users/Julien/Desktop/text3.txt", "wb");
    fwrite(block,1,blockSize,outFile);
    fclose(outFile);
    return 0;
}


void bitStuffing(char* in, int begin) {
    printf("\nBEGIN STUFFING");
    printf("\nrem =%2d", begin);
    int i;
    for(i=begin; i<blockSize; i++) {
        in[i] = 0;
        printf("\ni =%1d | value =%1x\n     ",i, in[i]);
        myprint(in, i);
    }
    printf("\nEND STUFFING\n");
}


void myprint(char* content, int size)
{
    int i;
    printf("\n");
    for(i=0;i<size;i++)
    {
        printf("%2x",content[i]);
    }
    printf("\n");
}

This works as well like i want. Then i was sure that the problem didn't come from the bitStuffing

Thank's everybody

Now, i will slap my friend

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM